Этого треда уже нет.
Это копия, сохраненная 5 августа 2023 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
1642313548896.jpg85 Кб, 675x1200
Godot #22.02 785715 В конец треда | Веб
Добро пожаловать в тред любви, взаимопомощи и котиков, греющихся на параболической антенне с подогревом!

Краткий гайд по вкату в движок:
1. Читать документацию.
2. Качать примеры.
3. ПРОФИТ!

Ссылки
Новости движка: https://godotengine.org/news/
Скачать движок: https://godotengine.org/download/ или http://store.steampowered.com/app/404790/Godot_Engine/
Играть в игродела онлайн без регистрации: https://editor.godotengine.org/releases/3.4.rc1/godot.tools.html с дивана нельзя.
FAQ: https://docs.godotengine.org/ru/latest/about/faq.html
Документация: https://docs.godotengine.org/ru/latest/ https://docs.godotengine.org/en/stable/
Примеры качаются прямо в движке через свой магазин в отдельной вкладке AssetLib. Там есть всё - от платформера до чата.
Игры, созданные глобальными кириллами: https://steamcommunity.com/app/404790/discussions/0/412448792354265655/
Изумительный Годот: https://github.com/Calinou/awesome-godot https://github.com/godotengine/awesome-godot - подборка дополнений, модулей и минишоукейc.
Аддон для диалоговой системы: https://godotengine.org/asset-library/asset/833
Прекомпилер шейдеров: https://godotengine.org/asset-library/asset/977
Майндмаппинг проектов не отходя от кассы: https://godotengine.org/asset-library/asset/879
SmartShape для рисования 2D-террейнов без задней мысли: https://godotengine.org/asset-library/asset/715
Конвертор кваковских карт для ностальгирующих дидов: https://godotengine.org/asset-library/asset/446
Конвертер блендеровских моделей в формат сцен: https://docs.godotengine.org/en/stable/getting_started/workflow/assets/escn_exporter/index.html
Конвертер блендеровских файлов прямо в движок: https://github.com/V-Sekai/godot-blender Надо только в настройках проекта путь к blender.exe указать. Потом просто закидываешь .blend в папку и импортируется.

Книги
Анон упомянул книги, но не накидал годноты, поэтому вот вам две рандомные из гугла:
https://play.google.com/store/books/details/Godot_Engine_Game_Development_in_24_Hours_Sams_Tea
https://play.google.com/store/books/details/Chris_Bradfield_Godot_Engine_Game_Development_Proj

Для любителей пощекотать конпеляцию
Бинды LUA: https://github.com/perbone/luascript
Бинды JS: https://github.com/GodotExplorer/ECMAScript

Годнота от анона
- Для приверженцев опенсорца существует возможность распространять проекты в незапакованном формате. Просто скачай темплейт с оф.сайта и положи экзешник/эльфешник в папку с проектом, этого достаточно. Имя файлу можно задать любое. Дополнительно можешь вшить свою иконку в экзешник. После этого, запустившийся файл темплейта обнаружит рядом с собой файл project.godot и начнет грузить проект из него и из файлов, лежащих в распакованном виде в той же директории. Для запущенного таким образом проекта папка res:// становится доступна для записи (если это не ограничено правами доступа в системе).
- В версии 3.2 появилась возможность прикреплять pck к бинарнику. Не появилась, а вернулась - 2.х умел. Бриллиант для любителей однофайлового продукта!
- Редактор персонажей на основе makehuman: https://github.com/Lexpartizan/Go_MakeHuman_dot
- Тест-бенчмарк:
- - Веб-версия - https://govdot.herokuapp.com
- - Вишмастер для винды - https://govdot.herokuapp.com/4Anon.rar

Предыдущий: >>779036 (OP)

Архивный: https://arhivach.ng/thread/745079/
2 785723
>>785702 →

> чет мало инфы обо всем этом


В середине десятых я сидел в /tes/ в треде модамидопиливающих, и полностью изучил архитектуру моддинга тесачей (на примере скайрима, но как мы знаем, архитектура там одна и та же).
В годоте с некоторыми допущениями архитектура похожая. ПАК-файлы - это аналоги ESM, ESP и BSP файлов, ESM - это первый ПАК-файл, который грузится движком. Затем, при помощи встроенных функций, ты можешь загрузить другие ПАК-файлы. Очевидно, тебе нужно будет сделать удобный тебе внутриигровой менеджер загрузки и проверки ПАК-файлов. Необязательно с интерфейсом для игрока.
Далее. При загрузке стороннего ПАК-файла, его содержимое интегрируется в виртуальную файловую систему res://, она в документации числится как рид-онли, но этот момент не указывается (а зря, а может уже указывается, я доку давно не листал). Если в загруженном ПАК-файле имеются объекты с именами, совпадающими с уже имеющимися в res:// объектами, предыдущие объекты будут перезаписаны.
Таким образом, ты можешь не только добавлять контент модами, но и как гласит само слово мод - модифицировать игровой контент. Например, заменить стартовую локацию на почти такую же, но с дверью, которая поведёт игрока в локации из мода. Последовательность загрузки тоже будет важна, каждый следующий ПАК в последовательности загрузки при совпадении имён будет заменять объекты, добавленные/заменённые предыдущими ПАКами. Одним файлом ставишь скелеты с хвостами, другим файлом ставишь бронелифчики, ну ты понел, если моддил скайрим. Разумеется, чтобы была возможность замены таких вещей как скелеты и анимации, всё это на этапе сборки игры должно быть максимально разнесено по отдельным файлам. И вот эта задача - самая сложная: просчитать и продумать архитектуру, тщательно разложить всё по папочкам в res:// чтобы не запутаться через неделю.
Внутри виртуальной папки res:// тебе даже не потребуется как-то разделять контент на ванильный и моддерский. Эта папка аналогично внутренней базе данных FORM-объектов в тесачедвижке, там они тоже, как я помню, не имеют меток о своём происхождении (может я конечно и ошибаюсь). Менеджмент модами будет происходить на уровне реальной файловой системы и ПАК-файлов. А внутри неё пути исключительно по внутриигровой логике, что-то типа res://locations/location1 res://furniture/indoor/culture1/lamps/lamp1 res://creatures/animations/human/male/... где location1, culture1 и lamp1 - это какие-то реальные названия объектов по лору игры, а в human/male лежит например пак анимаций, скелет, стейтмашина.
2 785723
>>785702 →

> чет мало инфы обо всем этом


В середине десятых я сидел в /tes/ в треде модамидопиливающих, и полностью изучил архитектуру моддинга тесачей (на примере скайрима, но как мы знаем, архитектура там одна и та же).
В годоте с некоторыми допущениями архитектура похожая. ПАК-файлы - это аналоги ESM, ESP и BSP файлов, ESM - это первый ПАК-файл, который грузится движком. Затем, при помощи встроенных функций, ты можешь загрузить другие ПАК-файлы. Очевидно, тебе нужно будет сделать удобный тебе внутриигровой менеджер загрузки и проверки ПАК-файлов. Необязательно с интерфейсом для игрока.
Далее. При загрузке стороннего ПАК-файла, его содержимое интегрируется в виртуальную файловую систему res://, она в документации числится как рид-онли, но этот момент не указывается (а зря, а может уже указывается, я доку давно не листал). Если в загруженном ПАК-файле имеются объекты с именами, совпадающими с уже имеющимися в res:// объектами, предыдущие объекты будут перезаписаны.
Таким образом, ты можешь не только добавлять контент модами, но и как гласит само слово мод - модифицировать игровой контент. Например, заменить стартовую локацию на почти такую же, но с дверью, которая поведёт игрока в локации из мода. Последовательность загрузки тоже будет важна, каждый следующий ПАК в последовательности загрузки при совпадении имён будет заменять объекты, добавленные/заменённые предыдущими ПАКами. Одним файлом ставишь скелеты с хвостами, другим файлом ставишь бронелифчики, ну ты понел, если моддил скайрим. Разумеется, чтобы была возможность замены таких вещей как скелеты и анимации, всё это на этапе сборки игры должно быть максимально разнесено по отдельным файлам. И вот эта задача - самая сложная: просчитать и продумать архитектуру, тщательно разложить всё по папочкам в res:// чтобы не запутаться через неделю.
Внутри виртуальной папки res:// тебе даже не потребуется как-то разделять контент на ванильный и моддерский. Эта папка аналогично внутренней базе данных FORM-объектов в тесачедвижке, там они тоже, как я помню, не имеют меток о своём происхождении (может я конечно и ошибаюсь). Менеджмент модами будет происходить на уровне реальной файловой системы и ПАК-файлов. А внутри неё пути исключительно по внутриигровой логике, что-то типа res://locations/location1 res://furniture/indoor/culture1/lamps/lamp1 res://creatures/animations/human/male/... где location1, culture1 и lamp1 - это какие-то реальные названия объектов по лору игры, а в human/male лежит например пак анимаций, скелет, стейтмашина.
# OP 3 785727
Чо с архивачем, годаны?
С осени не могу нормально архив треда сделать, а сегодня вообще жёстко заглючил. Открываю через прокси, дополнения мозилы уже все поотключал, но всё равно он сначала загружается, а потом ХУЯК и белая пустая страница. ЧЯДНТ?
4 785732
>>85728 (Del)
Да, хорошо нарисовали. Мало контента с ней, только из-за нее и годотной головы годот имеет донаты, эти персы полюбились общественности.
5 785742
годот, подскажи - как писать код игры на С++? Лучше урок или пример или статью кинь

Хочу тут олдскульную игру сделать, а писать на питоне и шарпе не хочу - не нравится.
Вроде же как-то можно

В идеале вообще бы использовать годот как библиотеку, без редактора - редактор у меня другой - TrenchBroom, тем более что вроде для годота есть модуль загрузки карт из него
6 785743
>>85742

> Хочу тут олдскульную игру сделать


99% олдскульных игор делается в чистом си. Движки для них не нужны.
изображение.png4,7 Мб, 1920x1080
7 785745
>>85743
99% олдскульных игр на чистом си никто не доделывает до конца

Удачи тебе на чистом си сделать вот это с пикчи. Через десять лет расскажешь что получилось
timeline.png5 Кб, 389x168
8 785746
>>785413 →
>>785418 →
Извиняюсь, посоны. На следующий же день свалился с температурой, и переделал всё обратно до тех пор, пока снизу игра не появится.
Во-первых контейнеры просто растягивались на весь экран, хотя я делал примерно то же самое, что в другом проекте, где не растягивались. А во-вторых у меня в интерфейсе есть таймлайн, на котором отмечается окончание действий всех болванчиков, и сейчас он устроен как движущийся спрайт, про который я точно знаю, сколько пикселей в секунду он проезжает, и куда маркеры надо расставлять. Понятное дело, что это не сложнее вращающейся миникарты с отметками, но быстрым изменением типов ноды это не меняется, так что пусть пока костыль работает. Будет играться — переделаю нормально.
9 785759
>>85745
Сорян, не разглядел, что ты делаешь кваку.
Тогда тебе другое предложение. Поскольку ты всё равно делаешь в другом редакторе и "движок" тебе нужен как "библиотека", то тебе нужно юзать "движок", который изначально позиционируется как "библиотека". SDL или SFML.
Я специально беру определения в кавычки, потому что современная классификация инструментов разработки всё нихуёво переиначила со времён кваки.
Современные "движки" - это в первую очередь редакторы. А настоящие движки - это именно "библиотеки". Годот без редактора по своим возможностям приблизительно аналогичен уже вышеупомянутым SDL SFML, где-то лучше, где-то хуже.
Если тебе надо писать игру в IDE, с использованием стороннего движка, и ты настойчиво хочешь годот, то тебе нужно взять стабильные исходники и собственно говоря править их, дописывая к ним модули. А потом собрать бинарник, который в общепринятом смысле у нас тут зовётся шаблоном экспорта, а у тебя же это будет полноценный запускной файл игры, которой не нужен будет пак-файл для старта.
Но наебёшься конкретно, скрещивая ежа с ужом. В таком пайплайне девелопа тебе в третий раз повторюсь, выгоднее взять SDL или SFML, для них и гайдов поболее будет.
10 785761
>>785400 →

> Суп, gd, я делал HUD и обосрался. Дай, пожалуйста, гайд по тому, как правильно расставлять ЕБУЧИЕ КОНТЕЙНЕРЫ внутри ЕБУЧИХ КОНТЕЙНЕРОВ, чтобы они стояли на своём месте.


Сначала рисуешь интерфейс на бумаге. Продумываешь, как он будет выглядеть. Затем рисуешь макет в фотошопе или аналогах, выделяя каждый элемент в отдельный слой. Затем переносишь уже интерфейс в годот. Ебучие контейнеры перестанут быть ебучими, если ты декомпозируешь задачу и по пунктам задашь себе вопрос, что именно ты хочешь, а потом каждый пункт прогуглишь. Это немалая работа и вряд ли кто-то будет делать её вместо тебя.

> Я вообще смогу заставить TextureRect нормально двигаться из кода, или нунахуй?


Сможешь.
>>85746

> контейнеры просто растягивались на весь экран, хотя я делал примерно то же самое, что в другом проекте, где не растягивались


Настройки макета.

> быстрым изменением типов ноды это не меняется


position заменить на rect_position
11 785845
>>85838 (Del)
Ого! Выяснениями какое онемэ не онеме наш тред срачедауны ещё не рейдили. Репорт!
image.png125 Кб, 300x230
12 785862
>>85838 (Del)
Ты долбоеб, который не знает про чибиков и супер деформед.

>>85845
Ты параноик с синдромом жертвы.
13 785875
>>85864 (Del)
>>85862
>>85809 (Del)
Какие пропорции в Аниме-стиле, ты совсем шизоид?
Или ты очередной выпускник "школы XYХУЙ аниме-эдишон за 20 часов до Хаяо Миядзаки", в которой вас за 35 тысяч дрочили в несуществующие пропорции, академическое понятие чиби, но так и не научили рисовать?
0cc.jpg47 Кб, 633x640
14 785907
пиздос недавн ночью полчаса ебался с одним лейблом, пока делал локализацию, каковата хуя не хотел отображать строку на русском, я и строки дублировал и гуглил мб лейбл багует, в итоге понял что в шрифте тупа нет кириллицы
image.png1,6 Мб, 1500x844
15 785917
>>85907
Ебать ты кадр канеш, крепчай
16 785921
>>85838 (Del)
1. Ты неправильно измеряешь пропорции тела. Нужно измерять пропорции в головах персонажа, а не сравнивать его с другим персонажем. Пропорции - это соотношение между частями объекта, например, "голова составляет 1/5 роста" (или "рост 5 голов").
2. "Аниме-стиль" отличается от остальных чертами лица, в первую очередь это "большие стилизованные глаза" и "почти отсутствующий нос". Всё остальное - по желанию художника, хотя чаще всего тело нарисовано реалистично, но далеко не всегда. Особенно часто пропорции искажают в комичных сценах/жанрах.
3. Пропорции тела людей в аниме-стиле могут быть от "1 голова" ("колобок") до "9 голов" ("ноги от ушей"). Чиби - это обычно 2 или 3 головы, лоли - 3-4, ребёнок - 4-5, школьник - 6-7, взрослый - 7-8. В аниме, однако, не всегда пропорции тела соответствуют возрасту, можно встретить по-детски большеголовых взрослых. Также чем больше глаза относительно головы - тем, как правило, моложе персонаж, но это тоже не всегда так.
4. На конкретном рисунке Годетта нарисована как ребёнок: рост 5 голов, большие глаза, плоская грудь, пухлые короткие ручки. А теперь положи руки на стол и оставайся на месте...
5iOPw9a - Imgur.gif3,8 Мб, 500x378
17 785927
Хочу запилить в свою игру плейлист с интернет-радио, типа как к ETS2
Нашёл такое:
https://www.reddit.com/r/godot/comments/l4nzqg/c_any_way_to_stream_audio_from_internet_radio/
Но лагает, мля
Есть идеи, как фиксить? Или другие варики по реализации?
18 786201
>>86148 (Del)
if not fcknstupidnode == null: fcknstupidnode.remove()
Как это сказать правильно по гдскриптовски? В который раз вылетает на этой строчке из-за того, что нода таки null.
19 786203
>>86201
If !fcknstupidnode:
Print('i am null')
20 786207
>>86203
Двачую этого. Или так, если нравится буквами:
>>86201

> if not fcknstupidnode: fcknstupidnode.remove()


Неочевидный нюанс гдскрипта.
Выражение с одной переменной в блоке иф - это уже внутренняя проверка средствами типа этой переменной на нуль, на ноль, на пустую строку. Когда же ты дописываешь ==, годот пытается вывести результат из выражения, и падает в экзепшн.
21 786212
>>86209 (Del)
Это и есть фантазии. Своим условием ты отрицаешь ноду, а не неравенство.
1614726977739.jpg155 Кб, 640x1990
22 786216
>>86207
>>86203
Спасибо, посоны, выручили. Только там наоборот, отрицание не нужно, мы как раз и удоляем непустую ноду, но я понел.

>Когда же ты дописываешь ==, годот пытается вывести результат из выражения, и падает в экзепшн.


Падал он на втором выражении, потому что через корявое условие проходила пустая нода, и он ругался, что у null нет такого метода. Причём проходила она почему-то только если раньше она появлялась, а потом удалялась.
В общем, всё вело себя как говно, и больше не ведёт, а почему — это интересный вопрос для будущих исследователей.
23 786220
не хочу учить гдскрипт или шарп ради своих говноподелий, как этот двиджок в плане секса визуал сриптинга?
24 786228
Скажите, а вы тоже сначала пишете 500+ строк скрипта, а потом делаете новый скрипт и копипастите кусками из старого, потому что переделывать старый становится слишком сложно? У меня так часто случается из-за того, что сделав одну систему, решаю фундаментально её переделать... Это нормально ведь? Все так делают?

>>86220

>визуал сриптинг


В Годо визуальный ЯП примерно такой же, как и везде: размещаешь на бесконечном полотне блоки и соединяешь их линиями. Проблема в том, что визуальные ЯП принципиально неудобны для чего-то сложнее хэллоу ворлда. Даже простые вещи будут занимать много места на экране, а для их создания придётся много работать мышкой, постоянно переключаясь на клавиатуру для ввода имён и значений. Лучше сразу учи GDScript, сэкономишь себе кучу времени и телодвижений, т.к. мышку трогать вообще не будешь. Чисто логически программы одинаковы и там, и там, визуальный ЯП только добавляет графическое изображение потока выполнения программы (те самые линии между блоками), но у настоящего программиста эта картинка всегда в голове.

>>85927

>интернет-радио


>лагает


Либо снижай частоту потока (обычно радио доступно с разной частотой потока, как и любое аудио), либо добавляй кэш в несколько секунд. Т.е. сначала стартуешь загрузку данных потока в кэш, а через 10 секунд начинаешь воспроизведение: так, если загрузка будет тормозить, у тебя в запасе целых 10 секунд, предотвращающих заикание звука. Так все плееры делают.

>>86216

>Причём проходила она почему-то только если раньше она появлялась, а потом удалялась.


Нужно учитывать, что в переменной не обязательно будет null, иногда могут получаться указатели на уже несуществующую ноду (или существующую, но не ту, что ты ожидаешь). Так что тестить ноду на существование через "if node:" небезопасно. Вроде бы это хотят как-то исправить в 4.0, но я так и не понял, как.
25 786230
>>86228

>в переменной не обязательно будет null


И он, кстати, действительно не будет, до этого указателя я не дотягивался (точнее, дотягивался, но кривовато). Проверять нужно, похоже, через «is_instance_valid».

>Это нормально ведь? Все так делают?


Нет, я горожу наследования. Недавно хотел вытащить бота из старого проекта в новый (ну фигли там сложного, и тут и там ходит по тайловой карте и ищет всех, у кого есть полоска HP, чтобы её опустошить) и офигел от того, чего я там успел нагородить. В итоге от бота удалось спасти только десять строчек в автомате состояний, которые учили его шляться в рандомном направлении.
Вот и на днях я слил нафиг два огромных скрипта (управлявших плейсхолдером-врагом и плейсхолдером-играбельным юнитом) в один роскошный суперкласс, потому что задолбался держать в голове костыли, и решил всё сделать с бумажкой и ручкой. Ну зато пока что у меня почти нет классов-прослоек, у которых скрипт объявляет две-три очень нужные переменные и не делает ничего.
redditsave.comgodscript-axivgkm4l3c81.webm2 Мб, webm,
398x480, 0:15
26 786237
Мемчики подъехали)

>>86230

>is_instance_valid


RIP https://godotengine.org/qa/52163/

>In Godot 3.x, is_instance_valid might not be enough to detect when an object has been freed, because your reference to the freed object might return a random different (non-freed) object. Using a WeakRef instead can work around the issue, but only if your code is compatible with WeakRef not contributing the the object's reference count.


>It looks like this issue will be fixed in Godot 4.0, and is_instance_valid will be removed.



>Нет, я горожу наследования


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

>слил нафиг два огромных скрипта


>в один роскошный суперкласс


Я наоборот, стараюсь отделять данные/методы в отдельные классы, когда кода становится слишком много и он имеет чёткие границы, по которым можно выделить отдельные классы.
27 786238
>>86237

>Мемчики


>)


Пиздец, пикабушники блядь.
28 786239
>>86230
Вообще то скрипты которые объявляют 2-3 сеттера это нормально. Это слой даты. Он нужен, чтобы не было циклических зависимостей.
29 786240
>>86237
Ну ладно. Будет продолжать вылетать — просто добавлю в скрипт ноды указатель на того, кто её породил, чтобы он её окончательно и убивал, это даже не будет очень костыльно.
Да и вообще, если кодя, ты нарываешься на баги и ограничения IDE/движка/языка, значит ты наконец-то написал что-то посложнее A+B и, возможно, оно представляет собой некоторую ценность. Аутотренинг закончен.

>речь о переписывании архитектуры "почти с нуля"


Ну не всего проекта, конечно, но последняя «уборка» у меня перекосоёбила половину всего проекта. Зато всякие проверки логики, чтобы механики работали всегда и на всех, а не через раз и если повезёт, теперь все примерно в одном месте. Пока я новых и корявых не надабавляю, для которых обязательно нужно будет проверять флаг чистая ли жопа, вызывая его через гланды.
Причём многое странное легаси, про которое я не уверен, что буду использовать (в том числе из других проектов, ага), всё ещё на месте.
30 786242
>>86240
Нельзя детям знать о родителях. Родители должны законнектить сигнал к ребенку и ждать сигнала.
31 786243
>>86238

>пикабушники


Ты так говоришь, будто бы реддит не пикабу.

>>86235 (Del)

>с пакет менеджерами


Ты имеешь в виду, создать плагин, который потом импортировать в новые проекты? Но чем это отличается от ручного копипаста файлов, если это будет копия файлов плагина? На вкладке AssetLib вроде бы можно задать localhost, но непонятно, что Godot ожидает, в консоли ошибка "Invalid URL scheme: https://". Можно как-то сделать свою локальную библиотеку ассетов?

>>86240

>просто добавлю в скрипт ноды указатель на того, кто её породил


Правильно, управлять созданием и освобождением объекта должен только один объект. Если несколько объектов имеют возможность освободить один общий объект, неизбежны рандомные ошибки доступа, которые, хуже всего, могут проявиться лишь спустя время. Потом распутывать клубок связей - кто кого освобождает и как сообщить остальным, что теперь это ссылка в никуда. А регулярные проверки "это существует?" вряд ли хорошо сказываются на производительности...

>странное легаси, про которое я не уверен, что буду использовать


Такое я убираю в папку "ИмяПроекта.Legacy" на тот случай, если вдруг понадобится вернуть в проект, но чтобы не мешалось в работе над актуальными частями проекта. Правда, не уверен на счёт уместности термина "legacy", но ничего умнее не придумал ("легаси" вроде как обозначает рабочие части проекта, которые никто уже несколько лет не трогал, но продолжающие использоваться в актуальных билдах - уже никто не помнит, кто и как этот код написал, но на нём держится весь проект; я же обозначаю так части проекта, которые уже вышли из употребления, но всё ещё могут пригодиться).

>>86242

>Нельзя детям знать о родителях


Да? А как, по-твоему, работает get_parent()?

>законнектить сигнал к ребенку и ждать сигнала


А разве можно коннектиться к вызову queue_free()? Чтобы если кто-то вызывал child.queue_free(), его родитель выполнял child = null?
32 786244
>>86243
Нельзя детям знать о родителях концептуально, а не из кода. Это создаёт циклические зависимости.
33 786251
>>86228

>Проблема в том, что визуальные ЯП принципиально неудобны для чего-то сложнее хэллоу ворлда.



Для шейдеров удобная штука судя по всему. Смотрел на одном стриме, как автор пилит шейдеры для игрушки через визуальный скриптинг. Понравилось то, что есть возможность предпросмотра каждого этапа.
Однако сам предпочитаю код для этого
34 786252
>>86243
Можно как-то сделать свою локальную библиотеку ассетов?
Да, конечно.
https://github.com/godotengine/godot-asset-library

Можно даже свою мелковесную реализацию написать, используя их протокол.
https://github.com/godotengine/godot-asset-library/blob/master/API.md
35 786266
>>86244

>знать о родителях концептуально


Это как?

>циклические зависимости


В чём здесь циклическая зависимость?
1. Создаём ребёнка, сообщая ему self. Он сохраняет self в owner.
2. Когда кто-то запрашивает удаление ребёнка, ребёнок обращается к owner, чтобы тот обнулил свою ссылку на этого ребёнка. Или запретил удаление ребёнка, если он ему всё ещё нужен.

>>86246 (Del)

>type: copy


Я про это и говорил - по сути ты просто копируешь файлы, и это ничем не отличается от ручного копирования. Вот на Паскале можно указать компилятору в файле конфигурации ссылки на любые папки, в которых лежат нужные модули, и компилятор всё прекрасно найдёт, а в Годо мы ограничены папкой res://, это очень неудобно. Единственным выходом из ситуации я вижу использование https://ru.wikipedia.org/wiki/Жёсткая_ссылка

>>86251

>есть возможность предпросмотра каждого этапа


Да, для шейдеров/материалов/постпроцессинга визуальный редактор реально полезен. А для абстрактной логики лучше простым текстом писать.

>>86252
Ясно, довольно сложно получается для локальной библиотеки, полноценный сервер нужно настраивать. Я думал что-то вроде готового приложения, запускаешь и всё.
Без имени.png6 Кб, 248x181
36 786280
>>86243

>А разве можно коннектиться к вызову queue_free()?


Так можно queue_free() вызывать внутри своей процедуры и выпускать сигнал в предыдущей строчке. Кстати, я думаю, это мне подойдёт больше всего.
Кстати, сигнал tree_exited разве не вызывается, когда объект пропадает? Или он вызывается, когда его от родителя отрывают?
37 786285
>>86280

>Кстати, сигнал tree_exited разве не вызывается, когда объект пропадает? Или он вызывается, когда его от родителя отрывают?


Когда из дерева сцены выходит.

>void _exit_tree ( ) virtual


>Called when the node is about to leave the SceneTree (e.g. upon freeing, scene changing, or after calling remove_child in a script). If the node has children, its _exit_tree callback will be called last, after all its children have left the tree.


>Corresponds to the NOTIFICATION_EXIT_TREE notification in Object._notification and signal tree_exiting. To get notified when the node has already left the active tree, connect to the tree_exited.


>tree_exited ( )


>Emitted after the node exits the tree and is no longer active.


>tree_exiting ( )


>Emitted when the node is still active but about to exit the tree. This is the right place for de-initialization (or a "destructor", if you will).


https://docs.godotengine.org/en/stable/classes/class_node.html
Напоминаю: вся эта информация встроена в редактор, можно открыть поиск по F1 или нажать кнопку "doc" (с лупой) сверху справа на панели инспектора ноды. Учитесь читать документацию, чтобы не задавать глупых вопросов...
38 786291
Посоветуйте, как лучше делать настраиваемых/генерируемых персонажей? Есть мысль собрать скелет прямо в Годо, натянуть на него меш инстансы и анимировать непосредственно в Годо. Просто я не понимаю, как это делать в Блендере, что именно ожидает Годо от модельки персонажа из Блендера?

Я так понимаю, если персонаж модульный, на него уйдёт сразу пара десятков дроуколлов, ведь каждая деталь рендерится независимо? Как быть со стыками между модулями, если персонаж не из кубиков?

Моделить лицо или натягивать рисунок лица текстурой?
39 786298
>>86266
Для того, чтобы создать ребенка, нужен парент. И для того, чтобы создать парент, нужен ребенок. А скрипты для них ещё не сформированы. И того, циклическая зависимость. Да, ТК годо высокоуровневый, от тебя это прячут. Но это признаки лапшекода.
40 786420
>>86298

>Для того, чтобы создать ребенка, нужен парент.


Это очевидно.

>И для того, чтобы создать парент, нужен ребенок.


С чего вдруг? Ребёнок не подключается к родителю как к модулю, не обращается к его методам (только к абстрактным), он только хранит в себе ссылку, которую сам же родитель дал при создании экземпляра ребёнка.

>А скрипты для них ещё не сформированы.


С чего вдруг? В скрипте ребёнка нет явных обращений к родителю, он может считать своим родителем кого угодно, в этом вся прелесть ООП. Ничто не мешает скомпилировать код ребёнка, потому что в нём нет ссылок на какие-либо другие файлы/модули/классы/etc. В нём есть только поле owner, которое может хранить ссылку на экземпляр любого класса (в ООП, даже строго типизированном).

На языках типа Паскаля это тоже решаемо, если ты об этом. Там есть универсальный тип Pointer, который хранит любые указатели. Слабая типизация, если что - это тип Variant, который может хранить вообще что угодно, а не только указатели. Вот GDScript построен на Variant, а я предлагаю использовать универсальный Pointer, так понятнее?

Если же тебе нужно непосредственно подключаться к модулю родителя, то на Паскале для этого можно подключить модуль родителя в блоке имплементации, таким образом циклической зависимости не будет (но нельзя обращаться к типам модуля родителя из интерфейсной части модуля ребёнка, отсюда Pointer).

Т.е. получается как-то так:

unit ParentUnit;
interface
uses ChildUnit;
type
TParent = class
FChildren: array of TChild;
...
procedure FreeChild(Child: TChild);
...
end.

unit ChildUnit;
interface
type
TChild = class
FParent: Pointer;
...
procedure AskParentForFreedom;
...
implementation
uses ParentUnit;
...
procedure TChild.AskParentForFreedom;
begin
TParent(FParent).FreeChild(self);
end;
...
end.

Я протестировал, всё работает, никакой циклической зависимости не возникает - компилируется, создаётся, очищается и т.д.
40 786420
>>86298

>Для того, чтобы создать ребенка, нужен парент.


Это очевидно.

>И для того, чтобы создать парент, нужен ребенок.


С чего вдруг? Ребёнок не подключается к родителю как к модулю, не обращается к его методам (только к абстрактным), он только хранит в себе ссылку, которую сам же родитель дал при создании экземпляра ребёнка.

>А скрипты для них ещё не сформированы.


С чего вдруг? В скрипте ребёнка нет явных обращений к родителю, он может считать своим родителем кого угодно, в этом вся прелесть ООП. Ничто не мешает скомпилировать код ребёнка, потому что в нём нет ссылок на какие-либо другие файлы/модули/классы/etc. В нём есть только поле owner, которое может хранить ссылку на экземпляр любого класса (в ООП, даже строго типизированном).

На языках типа Паскаля это тоже решаемо, если ты об этом. Там есть универсальный тип Pointer, который хранит любые указатели. Слабая типизация, если что - это тип Variant, который может хранить вообще что угодно, а не только указатели. Вот GDScript построен на Variant, а я предлагаю использовать универсальный Pointer, так понятнее?

Если же тебе нужно непосредственно подключаться к модулю родителя, то на Паскале для этого можно подключить модуль родителя в блоке имплементации, таким образом циклической зависимости не будет (но нельзя обращаться к типам модуля родителя из интерфейсной части модуля ребёнка, отсюда Pointer).

Т.е. получается как-то так:

unit ParentUnit;
interface
uses ChildUnit;
type
TParent = class
FChildren: array of TChild;
...
procedure FreeChild(Child: TChild);
...
end.

unit ChildUnit;
interface
type
TChild = class
FParent: Pointer;
...
procedure AskParentForFreedom;
...
implementation
uses ParentUnit;
...
procedure TChild.AskParentForFreedom;
begin
TParent(FParent).FreeChild(self);
end;
...
end.

Я протестировал, всё работает, никакой циклической зависимости не возникает - компилируется, создаётся, очищается и т.д.
41 786424
>>86420
Блин, ошибся в нескольких местах. Ну, не важно, главное что ничто не мешает скомпилировать модуль ребёнка, хотя он и обращается к методам из модуля родителя.

И да, конечно, компилятор (FPC) сначала читает модуль родителя, потом компилирует модуль ребёнка, потом (до)компилирует модуль родителя.

Но это всё не касается GDScript, скрипты которого пока что вообще никак не компилируются и ты можешь обращаться к любым методам, а уже интерпретатор будет ругаться, если в конкретный момент времени требуемого метода у объекта по ссылке не окажется... Т.е. никаких упоминаний родителя в скрипте ребёнка на GDScript вообще не нужно, если не преследовать строгую типизацию.

>>86298

>признаки лапшекода


Код-лапша - это когда у тебя сразу несколько объектов хранят ссылки на один общий объект, и могут в любой момент его очистить, не предупредив всех остальных. В данном случае мы избавляемся от этой лапши, каждый раз запрашивая ребёнка из родителя... хотя, если честно, ничто не мешает запросить освобождение ребёнка непосредственно у родителя...
Recolor.gif9,5 Мб, 1893x939
42 786442
Сделал вот такой прототип. Игрок не может пройти через дверь определенного цвета два раза подряд.
Больше всего мучился с защитой от дурака. Игрок не поменяет цвет если зайдет в дверь и пойдет обратно. Только если он прошел насквозь.

Планирую замутить головоломку на этой системе
43 786443
>>86424
Как только ты начнёшь пользоваться типизацией в виде class_name, твоя идиллия порушится. И важно, чтобы повышать свой навык программирования, сделать этот переход (к типизации) как можно раньше.
44 786453
>>86443
Я соблюдаю типизацию, указываю типы во всех местах, где это возможно и где мне не нужны варианты. Но вот class_name очень специфическая штука на самом деле, нужна она только в двух случаях: если нужно сделать ООП-потомка годы, либо если нужно создавать свой собственный ресурс. Обычные ноды ничто не мешает инстансить без названия.

Или ты предлагаешь каждому скрипту давать уникальное имя и указывать в параметрах функций эти имена вместо имён классов стандартных нод? По-моему, так поле доступных имён слишком быстро переполнится, а ограничивать его никак не выйдет. Вот на Паскале ты явно подключаешь модуль через uses и только тогда получаешь доступ к его именам, а на GDScript у тебя постоянный доступ ко всем скриптам в проекте.

И это при том, что даже стандартные классы забивают красивые имена. Вот, например, класс World - я захотел создать глобальный синглтон контейнер данных о мире World, но класс с таким именем уже существует! А как мне развивать собственный генератор случайных чисел? RandomNumberGenerator уже забит стандартным классом, а как я должен называть это по-другому? Вот из-за такой фигни пользоваться class_name жутко неудобно и поэтому нельзя разбрасываться именами на всякую чепуху.

Тем более что большинству функций не нужны какие-то особенные данные, если функция ждёт позицию игрока - она должна запрашивать не Player, а Spatial, потому что позиция объявляется в Spatial, а большего этой функции знать не нужно.
45 786477
>>86453
Нет, если функция запрашивает году, которую ты облагородил своим скриптом, то это уже не spartal.
46 786491
>>86442

>Игрок не поменяет цвет если зайдет в дверь и пойдет обратно. Только если он прошел насквозь.


И как реализовал? Я бы схоронил координаты центра в момент касания двери и в момент, когда хитбокс игрока выходит из хитбокса двери, и проверил, лежат ли они по разные стороны от двери. Хотя думаю, держать в каждой комнате свою зону — решение ничем не хуже.
47 786569
>>86491
Просто запиши объект последней двери в персонажа.
изображение.png61 Кб, 844x304
48 786585
>>86491
Dot Product
Код двери:
49 786586
>>86491
>>86585
Ну это по сути то же самое что ты предложил
50 786632
>>86585
А если зашёл в вертикальную дверь снизу, а вышел сверху с той же стороны? Угол >90°, твой код скажет, что игрок прошёл через дверь. Теоретически это фиксится дизайном маленькой узкой двери, но что, если левел дизайнер захочет сделать большую дверь через весь уровень? Ненадежное решение, короче. Будет лучше спавнить по бокам двери две Area размером с дверь (они должны соприкасаться или пересекаться внутри двери), и следить за тем, в каком порядке игрок входит и выходит из них:
1. Зашёл в А, зашёл в Б, вышел из Б, вышел из А - не прошёл.
2. Зашёл в А, зашёл в Б, вышел из А, вышел из Б - прошёл.
Это позволит делать двери любой длины и любой ширины и не зависит от origin/position двери и персонажа, т.к. учитывает только коллиженшейпы. Также возможно сделать двери произвольной формы, но тогда коллиженшейпы нужно сделать вручную.

>>86477
Чисто технически, Spatial со скриптом остаётся Spatial. Скрипты GDScript только выглядят как классы, на деле ты не создаёшь собственного потомка Spatial, а только изменяешь поведение конкретного Spatial. Читал об этом где-то, не помню уже.

В любом случае, не вижу смысла множить лишние сущности, давая имена всем скриптам. В каких-то особых ситуациях это может быть нужно, но в общем случае - нет.
51 786635
>>86632

>А если зашёл в вертикальную дверь снизу, а вышел сверху с той же стороны?


Уже размышлял над этим. В таком случае придется дописать немного и вместо вектора между центрами игрока и двери сравнивать вектора между центром игрока и точкой первой и последней коллизии.

Что касается твоего варианта - понадобится много бойлерплейта
52 786639
>>86635

>понадобится много бойлерплейта


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

Попробовать самому сделать что ли?..
53 786643
Пагни, а можете кратко пересказать, что добавили в движок по сравнению с 3.2? А то я смотрю, щас уже 3.4+ версия, но вот открыл, бегло оглядел и изменений особых не увидел. Ченджлоги обычно пишут только в сравнении с предыдущей версией. Можете тезисно самое-самое главное обозначить плиз?
54 786649
>>86639

>Попробовать самому сделать что ли?..


Я сделяль! Это оказалось довольно просто и прикольно, хотя некоторые странные глюки я не смог отловить. Но мне никогда не нравились головоломки и я не представляю, что можно сделать на основе этой механики, так что продолжать, скорее всего, не буду. Кстати, с одним типом двери слишком скучно - я сделал второй тип (галочка в скрипте), который пускает только определённый цвет, вот тут уже можно какие-то интересные головоломки придумать, но мне опыта в головоломках на это не хватает.

Персонаж от другой моей попытки сделать 2D игру, управляется моим скриптом, который превращает мышь в виртуальный джойстик. Делал ещё летом, но мотивация упала - забросил...

>>86442 >>86585
Я правильно понимаю, что у тебя персонаж переключает свои физические слои, когда ловит сигнал "player_passed"? Я решил это по-другому, с переключением свойства disabled (через call_deferred) у CollisionShape2D StaticBody2D двери, а цвет отправляю игроку через аргумент body. Это, теоретически, позволяет иметь сколько угодно разных цветов (или других параметров), не ограничивая себя набором физических слоёв. Хотя, возможно, именно поэтому у меня иногда проявляются глюки (на видео глюков нет, проявляется очень редко: то дверь не пускает, хотя должна, то цвет будто бы не меняет, то пропускает раньше времени, при этом воспроизвести один и тот же глюк дважды не удаётся). Ещё одна особенность моего подхода в том, что открытая игроком дверь может пропустить любую другую сущность, пока игрок находится в двери, что может быть как преимуществом, так и недостатком...
55 786651
>>86649

>персонаж переключает свои физические слои


Нет, так же через disabled для всех дверей (Через call_group())
изображение.png307 Кб, 829x601
56 786653
>>86649
Я сделяль!
Годно. Тему с дверью, которая пропускает определенный цвет тоже уже реализовал.

> что можно сделать на основе этой механики


Вдохновлялся пикрилом, но когда реализовал понял что тоже не могу придумать почти ничего нового с одной этой механикой, поэтому буду вводить другие.
57 786660
>>86651

>disabled для всех дверей


Понятно. Наверное, это меньше глюков вызывает. У меня все двери изначально закрыты и открываются прямо перед тем, как игрок в них упирается, и затем закрываются, когда игрок выходит из них (в любом направлении). Сделал так из расчёта поддержки сущностей кроме игрока и визуализации открытия/закрытия двери.

>>86653

>Годно.


Спасибо.

>тоже не могу придумать почти ничего нового с одной этой механикой, поэтому буду вводить другие.


Мне приходит на ум такое:
1. Сделать длинные коридоры, которые не помещаются на весь экран, чтобы игрок был вынужден запоминать взаимосвязи между удалёнными друг от друга комнатами. Одного этого хватит на несколько уровней, т.к. хоть уровни и похожи, каждый нужно решать с нуля и это займет какое-то время.
2. Добавить ящики как в сокобане, но разных цветов, чтобы можно было проносить только определённым маршрутом. Ящики будут перекрашиваться дверями как и игрок. Ящик нужно поставить, к примеру, на кнопку, чтобы открыть или перекрасить какую-нибудь дверь. Кнопки тоже могут быть цветными - кнопку может нажать только игрок или ящик соответствующего цвета.
3. Добавить мобов, которые активно ходят по комнатам. Либо агрессивные - их нужно избегать, либо пассивные - их можно использовать как ящики. Тут как нельзя кстати пригодится то, что все двери на уровне работают независимо друг от друга. Ещё интереснее: игрок может пропустить моба через дверь неподходящего ему цвета, если откроет эту дверь своим телом. Аналогично моб может открыть своим телом дверь для игрока неподходящего цвета.
4. Добавить двери, кнопки или другие предметы, которые не перекрашивают игрока целиком, а смешивают его цвет: зелёный игрок может взять красный и стать жёлтым или взять синий и стать бирюзовым. Повторное применение (если предмет не потратился) приближает игрока к чистому цвету (красный или синий).
5. Можно создать лабиринт из цветных зон: скажем, красная дорожка внутри синих "стен", обратно идёшь соответственно по синей дорожке внутри красных "стен". Но я такое не смог сделать, т.к. у меня только две грани прямоугольника могут надёжно служить входом или выходом (т.к. там смещение Area на N пикселей по одной из осей).
6. Можно добавить пушки, которые стреляют краской. Если попал под снаряд такой пушки - меняешь цвет и, соответственно, уже не можешь пройти через какую-то дверь, но можешь через другую. Агрессивные мобы из пункта 3 тоже могут вместо убийства просто окрашивать игрока в свой цвет, что может быть игроку как полезно, так и вредно.
7. Совмещая 2 и 3: транспорт определённого цвета позволяет игроку проехать через дверь (и провезти груз), даже если сам игрок имеет неподходящий цвет. Транспорт может быть управляемым или автоматическим (вагонетки, следующие по маршруту).
8. Можно сделать стены уровня вариантом двери. Чтобы пройти сквозь стену, нужно иметь её цвет (серый). Но добыть этот цвет можно только на определённых уровнях и сделать это сложно, а до самой идеи "пройти сквозь стены уровня" нужно ещё додуматься.

Если интересно, я делал этого персонажа для 2D игры про город, но забросил из-за того, что это оказалось сложно и недостаточно интересно для меня, мне больше нравится 3D версия, со свободной камерой и объёмной графикой. Но пока делал этот прототип сегодня, подумалось, что можно было бы вставить такие головки в качестве мини-игры в игру про город. Что-нибудь типа секретного подземелья, пройдя который получаешь крутую вещь. Мне кажется, я видел что-то похожее (мини-игра головоломка) в Retro City Rampage, но точно не помню, да и игру я так и не прошёл до конца.
57 786660
>>86651

>disabled для всех дверей


Понятно. Наверное, это меньше глюков вызывает. У меня все двери изначально закрыты и открываются прямо перед тем, как игрок в них упирается, и затем закрываются, когда игрок выходит из них (в любом направлении). Сделал так из расчёта поддержки сущностей кроме игрока и визуализации открытия/закрытия двери.

>>86653

>Годно.


Спасибо.

>тоже не могу придумать почти ничего нового с одной этой механикой, поэтому буду вводить другие.


Мне приходит на ум такое:
1. Сделать длинные коридоры, которые не помещаются на весь экран, чтобы игрок был вынужден запоминать взаимосвязи между удалёнными друг от друга комнатами. Одного этого хватит на несколько уровней, т.к. хоть уровни и похожи, каждый нужно решать с нуля и это займет какое-то время.
2. Добавить ящики как в сокобане, но разных цветов, чтобы можно было проносить только определённым маршрутом. Ящики будут перекрашиваться дверями как и игрок. Ящик нужно поставить, к примеру, на кнопку, чтобы открыть или перекрасить какую-нибудь дверь. Кнопки тоже могут быть цветными - кнопку может нажать только игрок или ящик соответствующего цвета.
3. Добавить мобов, которые активно ходят по комнатам. Либо агрессивные - их нужно избегать, либо пассивные - их можно использовать как ящики. Тут как нельзя кстати пригодится то, что все двери на уровне работают независимо друг от друга. Ещё интереснее: игрок может пропустить моба через дверь неподходящего ему цвета, если откроет эту дверь своим телом. Аналогично моб может открыть своим телом дверь для игрока неподходящего цвета.
4. Добавить двери, кнопки или другие предметы, которые не перекрашивают игрока целиком, а смешивают его цвет: зелёный игрок может взять красный и стать жёлтым или взять синий и стать бирюзовым. Повторное применение (если предмет не потратился) приближает игрока к чистому цвету (красный или синий).
5. Можно создать лабиринт из цветных зон: скажем, красная дорожка внутри синих "стен", обратно идёшь соответственно по синей дорожке внутри красных "стен". Но я такое не смог сделать, т.к. у меня только две грани прямоугольника могут надёжно служить входом или выходом (т.к. там смещение Area на N пикселей по одной из осей).
6. Можно добавить пушки, которые стреляют краской. Если попал под снаряд такой пушки - меняешь цвет и, соответственно, уже не можешь пройти через какую-то дверь, но можешь через другую. Агрессивные мобы из пункта 3 тоже могут вместо убийства просто окрашивать игрока в свой цвет, что может быть игроку как полезно, так и вредно.
7. Совмещая 2 и 3: транспорт определённого цвета позволяет игроку проехать через дверь (и провезти груз), даже если сам игрок имеет неподходящий цвет. Транспорт может быть управляемым или автоматическим (вагонетки, следующие по маршруту).
8. Можно сделать стены уровня вариантом двери. Чтобы пройти сквозь стену, нужно иметь её цвет (серый). Но добыть этот цвет можно только на определённых уровнях и сделать это сложно, а до самой идеи "пройти сквозь стены уровня" нужно ещё додуматься.

Если интересно, я делал этого персонажа для 2D игры про город, но забросил из-за того, что это оказалось сложно и недостаточно интересно для меня, мне больше нравится 3D версия, со свободной камерой и объёмной графикой. Но пока делал этот прототип сегодня, подумалось, что можно было бы вставить такие головки в качестве мини-игры в игру про город. Что-нибудь типа секретного подземелья, пройдя который получаешь крутую вещь. Мне кажется, я видел что-то похожее (мини-игра головоломка) в Retro City Rampage, но точно не помню, да и игру я так и не прошёл до конца.
58 786966
Делаю внутриигровую палитру тайлов для рисования ими по тайлмапе. Построена она должна быть, ессно, на "зелёных" интерфейсных нодах, иначе заебусь с наследованием и масштабированием. Ессно, отдельную текстуру для каждого тайла рисовать тупо, надо их как-то выковыривать из тайлмап-текстуры. Но TextureButton не умеет делать Region, как это умеет обычный спрайт. Соответственно, вопрос: а как это принято делать? Ну, в смысле, существует же много внутриигровых редакторов карт, верно? И в них, если доступна тайлмапа, обычно даётся палитра тайлов, верно? То есть, существует какое-то общепринятое оптимальное решение для такого случая. Может, даже в Годоте какая-то нода имеет подходящие свойства?
59 787003
>>86967 (Del)
>>86966
Стоило чуть внимательнее этим заняться, как обнаружилось, что у тайлсета есть функция tile_get_texture(id). Берём тайлмапу, выковыриваем из неё тайлсет, у тайлсета выпрашиваем текстуру для конкретного тайла - тадам. Правда, то ли я где-то косячу, то ли ещё что, но он мне вместо текстуры плитки выдаёт всю исходную тайлмапную текстуру целиком.
60 787009
>>87005 (Del)
эээ и что мне с ним делать? Я пытаюсь выковырять текстуры отдельных тайлов, чтобы ими нарисовать TextureButton'ы. Баттоны не умеют в регион. Или ты предлагаешь ручками создавать текстуры из тайлмапной при помощи региона?
Может, какие-то другие интерфейсные ноды умеют в регион, а я не знаю?
61 787027
>>87009
Зачем тебе texturebutton, анонче? Используй обычный тайлмап и всю логику рисования пиши сам. Получай координаты мыши, преобразовывай их в координаты на тайлмапе и меняй тайл
62 787028
>>87011 (Del)

>вариант с шейдером


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

>Используй обычный тайлмап и всю логику рисования пиши сам


Тащемта именно поэтому. С кнопкой у меня ровно одна строчка кода, а работать будет и с мышью, и с тачем. Я всё-таки игру на движке делаю, а не собираю велосипед из костылей.

В общем, я нашёл решение, и оно работает.
1.В _реади из тайлмапы извлекаем текстуру через tile_get_texture(0)
2. Там же из текстуры извлекаем имадж через get_data().
3. Пишем функцию, в которой:
4. создаём новый имадж путём вырезания квадрата из полного имаджа тайлмапы
5. Создаём текстуру из этого имаджа и возвращаем её
6. Везде, где нужна текстура отдельного тайла, просто спрашиваем её у этой самой функции.
Ну и всё, при открытии или обновлении палитры тайлов (она у меня 4х4, что покрывает далеко не все плитки в тайлсете) каждой кнопке предлагаем в качестве текстуры выдачу нашей функции по разным координатам. Бонусом то же самое можно скармливать курсору-рисовалке, который вообще-то обычный спрайт и умеет в регион, но так проще и чище.
Пример.png14 Кб, 561x286
63 787029
>>86966

>тайлмап-текстуры


Это называется текстурный атлас.

>TextureButton не умеет делать Region


Потому что это не его обязанность.

>как это принято делать


Думаю, тебе нужно это: (пикрил)
https://docs.godotengine.org/en/stable/classes/class_atlastexture.html

>>86967 (Del)

>Сразу приходит в голову накинуть шейдер.


Велосипедописатель-шейдеролюб, ты?

>>87003

>tile_get_texture(id)


Эта функция не создаёт новую текстуру. Всё дело в том, что ты можешь добавить в TileSet сразу несколько текстур. Нумерация тайлов идёт от 0 и не зависит от текстур. Метод tile_get_texture(id) возвращает текстуру, к которой привязан тайл id.

>>87027

>всю логику рисования пиши сам


Ещё один велосипедописатель. Зачем вам вообще движок, берите SDL и пишите свои игры на нём, в 2D это очень просто, когда ты велосипедописатель по жизни.

>>87028

>tile_get_texture(0)


Ну а ежели ты решишь добавить вторую текстуру, м?

>извлекаем имадж через get_data()


А мог просто взять и preload("res://tiles.png")

>создаём новый имадж путём вырезания квадрата из полного имаджа тайлмапы


>Создаём текстуру из этого имаджа и возвращаем её


Ещё один велосипедописатель. Итого над одним тривиальным вопросом, который решается встроенными средствами движка, постаралось три велосипедописателя, один другого смекалистей. Тред велосипедописателей какой-то (я тоже).

>Везде, где нужна текстура отдельного тайла, просто спрашиваем её у этой самой функции.


Ох лол, ты придумал решение ещё хуже, чем с шейдерами. Почему хуже - сам догадаться должен, не маленький, но дам подсказку: подумой, зачем тебе вообще атласы нужны. Только не надо велосипедить кэширование текстур, есть встроенные средства (ResourceLoader) и проблема твоего подхода не только в этом.

>так проще и чище


Прям как в анекдоте, панчлайн - в самом конце. Зачот, пешы ещо!
Пример.png14 Кб, 561x286
63 787029
>>86966

>тайлмап-текстуры


Это называется текстурный атлас.

>TextureButton не умеет делать Region


Потому что это не его обязанность.

>как это принято делать


Думаю, тебе нужно это: (пикрил)
https://docs.godotengine.org/en/stable/classes/class_atlastexture.html

>>86967 (Del)

>Сразу приходит в голову накинуть шейдер.


Велосипедописатель-шейдеролюб, ты?

>>87003

>tile_get_texture(id)


Эта функция не создаёт новую текстуру. Всё дело в том, что ты можешь добавить в TileSet сразу несколько текстур. Нумерация тайлов идёт от 0 и не зависит от текстур. Метод tile_get_texture(id) возвращает текстуру, к которой привязан тайл id.

>>87027

>всю логику рисования пиши сам


Ещё один велосипедописатель. Зачем вам вообще движок, берите SDL и пишите свои игры на нём, в 2D это очень просто, когда ты велосипедописатель по жизни.

>>87028

>tile_get_texture(0)


Ну а ежели ты решишь добавить вторую текстуру, м?

>извлекаем имадж через get_data()


А мог просто взять и preload("res://tiles.png")

>создаём новый имадж путём вырезания квадрата из полного имаджа тайлмапы


>Создаём текстуру из этого имаджа и возвращаем её


Ещё один велосипедописатель. Итого над одним тривиальным вопросом, который решается встроенными средствами движка, постаралось три велосипедописателя, один другого смекалистей. Тред велосипедописателей какой-то (я тоже).

>Везде, где нужна текстура отдельного тайла, просто спрашиваем её у этой самой функции.


Ох лол, ты придумал решение ещё хуже, чем с шейдерами. Почему хуже - сам догадаться должен, не маленький, но дам подсказку: подумой, зачем тебе вообще атласы нужны. Только не надо велосипедить кэширование текстур, есть встроенные средства (ResourceLoader) и проблема твоего подхода не только в этом.

>так проще и чище


Прям как в анекдоте, панчлайн - в самом конце. Зачот, пешы ещо!
64 787030
>>87029
>>87028
Шизоиды делают тайлмап из кнопок и называют меня велосипедистом
Oilpaintingpalette.jpg53 Кб, 358x459
65 787031
>>87030

>тайлмап из кнопок


Ты пьян? Перечитай ещё раз: >>86966

>Делаю внутриигровую палитру тайлов


>внутриигровую палитру тайлов


>палитру тайлов


>палитру


https://ru.wiktionary.org/wiki/палитра
67 787034
>>87033

>Перечитал


>tile-get-texture


Врёшь.
>>87003

>tile_get_texture


>он мне вместо текстуры плитки выдаёт всю исходную тайлмапную текстуру целиком.


>>87029

>>tile_get_texture(id)


>Эта функция не создаёт новую текстуру. Всё дело в том, что ты можешь добавить в TileSet сразу несколько текстур. Нумерация тайлов идёт от 0 и не зависит от текстур. Метод tile_get_texture(id) возвращает текстуру, к которой привязан тайл id.



В следующий раз читай ветку целиком, прежде чем советовать.
68 787040
>>87034
>>87009

Я все еще не знаю в чем ваша проблема.

var tile_size = Vector2(16, 16)
onready var tileset = $tile_map.tile_set

func get_texture_by_tile_id(tile_id):
var tile_texture = tileset.tile_get_texture(tile_id)
var tile_texture_offset = tileset.tile_get_texture_offset(tile_id)
var tile_region = Rect2(tile_texture_offset, tile_size)

var atlas_texture := AtlasTexture.new()
atlas_texture.set_atlas(tile_texture)
atlas_texture.set_region(region)
return atlas_texture

$texture_button.texture_normal = get_texture_by_tile_id(0)
69 787043
>>87040
Хм. Когда я гуглил этот вопрос, то наткнулся на видос про эти атласы, но там было наоборот про то, как много мелких текстурок собрать в одну большую. Поэтому я решил, что это не оно.

>>87029

>Ну а ежели ты решишь добавить вторую текстуру, м?


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

>А мог просто взять и preload("res://tiles.png")


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

Но тащемта завтра-послезавтра перепилю на атласы, действительно. Пока поработает как есть, временно, пока буду рисовать графику и музыку писать, благо там этого совсем мало надо. И дальше всё, останется реализовать ещё одну фичу и нарисовать парочку демо-уровней, и можно будет релизить. А, и геймплейный видос записать.
1642841528664.png9 Кб, 1021x599
70 787045
>>86653

> буду вводить другие


Механика обмена цветами, братишка, атдуши рикаминдую. Суть токова. Игрок, неся в себе определённый цвет, проходя через дверь, обменивается с дверью цветами.
14081258469824.jpg118 Кб, 596x582
71 787047
>>87040

>Я все еще не знаю в чем ваша проблема.


>var atlas_texture := AtlasTexture.new()


>atlas_texture.set_atlas(tile_texture)


>atlas_texture.set_region(region)


>return atlas_texture


Ты дурака валяешь или правда глупый?
Обрати внимание на скриншот: >>87029

Тред велосипедистов и слоупоков.
ОП, в следующем треде так и напиши:

>Добро пожаловать в тред любви, взаимопомощи и слоупоков, запоздало советующих написать велосипед!


Ещё нужно Годетту в слоупока перекрасить.
Не в обиду слоупокам, вы молодцы, стараетесь.

>>87043

>как много мелких текстурок собрать в одну большую


Естественно. Прежде чем использовать атлас, его нужно собрать. Любой туториал про атлас должен начинаться с объяснения того, что такое атлас и как его сделать, а уже потом - как использовать.

>Тогда придётся переписывать половину игры.


В следующий раз будешь писать более гибкий код)

>Точно не решу, потому что на тайлмапе слишком много завязано.


А вот в Террарии, например, есть очень много разных атласов. Буквально на каждый тип блока - свой атлас. Потому что запихивать все блоки со всеми их вариациями в один файл было бы нерационально, если вообще возможно. Также в тайловых РПГ такое замечал, несколько отдельных атласов. И если задуматься о модах - вставлять в игру новые блоки проще всего отдельным атласом, чем модифицировать уже имеющийся.
72 787090
>>87061 (Del)

>тайлы не анимированные? Водичка не плещется?


А эти "2D игры с анимированными тайлами воды" сейчас здесь, на этой доске? Вы их видите?

>если анимированные, то они и так каждый кадр перерисовываются


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

>надо обвешивать вьюпортами, а потом в них ставить флаг update_mode = ONCE


То есть ты каким-то образом планировал обойтись без вьюпортов в тайловой 2D игре? Это же очевидно, там где много тайлов - должно быть запекание в текстуры. Анимированные не запечь, но они могут рисоваться отдельным слоем. TileMap вроде как делает это всё автоматически, для этого у него чанки есть.

>>87053 (Del)

>почему ты думаешь, что N объектов AtlasTexture лучше, чем вариант с шейдером?


Во-первых, чисто из-за дизайна системы. Чем меньше костылей и велосипедов, тем лучше. Если в движок уже встроена поддержка текстурных атласов, зачем писать шейдерный велосипед? Во-вторых, раз уж эта функция встроена в движок, она может быть как-то дополнительно оптимизирована внутри движка, или улучшена в новых версиях, а твой велосипед зависит только от тебя, и если ты в нём наложишь кучу говнокода - никто тебе не поможет. И в-третьих... ой, всё, я просто боюсь шейдеров, они так сложно выглядят, какие-то непонятные циферки непонятно откуда прилетают, что с ними делать непонятно, как этому вообще учиться, по туториалам что ли?
73 787094
>>87090
>>87053 (Del)

>почему ты думаешь, что N объектов AtlasTexture лучше, чем вариант с шейдером?


А, забыл самое главное. Даже если шейдер можно нацепить непосредственно на TextureButton, как ты планируешь переключать этот шейдер по событиям кнопки? С помощью AtlasTexture можно задать значения всем вариантам texture_ в TextureButton, просто загрузив несколько вариантов одного атласа с диска. Какими они будут внешне - вообще без разницы. А с шейдером даже если так и можно сделать, придётся править код шейдера, придумывать всякие процедурные рамки, затенения, подсветки и т.д. Короче куча лишней работы на плечи программиста, когда это должен делать дизайнер в своём растровом редакторе графики.

Шейдеры оправданы, когда обязательно нужно прикрутить сложный процедурный эффект, который неэффективно делать на процессоре или невозможно заготовить заранее в виде текстур. Вот не так давно видел пример шейдерного отражения в воде в 2D игре с видом сбоку - там кастомные шейдеры оправданы. А здесь тебе нужно сделать то, что уже есть в движке и хорошо работает - зачем писать свой шейдер?
74 787121
Что, кто-то использует меши CSG в релизе? >>785912 →

>объекты комбинировались из CSG примитивов



Экспортировал сцену с CSG примитивами в gltf (кстати, фича встроенная, никакого плагина не нужно), так тут такое... Ладно все треугольники отдельные, что в несколько раз умножает число вершин (как я понимаю, они не индексированы?), это легко пофиксить одной кнопкой в блендере. Но сами треугольники... ну вы поняли.

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

Надеюсь, в будущем улучшат... Хотя бы чтобы дырки реже получались, бесит туда-сюда таскать, чтобы дырка пропала.
75 787125
>>87061 (Del)

>У тебя что, тайлы не анимированные? Водичка не плещется?


Нет, игра - довольно минималистичный абстрактный пазл.
>>87090

>Чем меньше костылей и велосипедов, тем лучше. Если в движок уже встроена поддержка текстурных атласов, зачем писать шейдерный велосипед?


Удваиваю
>>87094

>Шейдеры оправданы, когда обязательно нужно прикрутить сложный процедурный эффект, который неэффективно делать на процессоре или невозможно заготовить заранее в виде текстур.


Утраиваю. Это главная причина, почему я не лезу в шейдеры, хотя и умею ими пользоваться: на стадии proof-of-concept они не нужны, их главное предназначение - делать красиво, а на геймплей они не влияют почти никогда. То есть, причина скорее идеологическая, весь код я буду держать в виде gd-скриптов до тех пор, пока не возникнет однозначная необходимость что-то кодить в ином виде.

Кстати, годаны, а что слышно по поводу луа-плагина? Уже юзабелен? Дебагать с ним можно прямо в годоте? Хотя бы номер строки с описанием ошибки говорит? Такой-то гибкий язык, гораздо логичнее, проще и красивее гдскрипта, хотелось бы в будущих проектах совместить его с таким-то удобным движком-комбайном.
76 787131
>>87127 (Del)

>не надо бояться шейдеров. Это просто инструмент,


Я не боюсь шейдеров. Я считаю, что этот инструмент предназначен для другого. А для моих задач есть атласы.

Вот у меня есть лобзик и циркулярка. Лобзик предназначен для криволинейных отпилов, циркулярка - для прямолинейных. Конечно, лобзиком можно отпилить прямо, если приложить направляющую. И не надо бояться этого инструмента, он не такой уж сложный в освоении. Но у меня, блин, циркулярка есть! Пусть даже ей тоже нужна направляющая, но этот инструмент хотя бы будет применяться по назначению, в отличие от.
Аналогия понятна?
77 787181
>>87122 (Del)

>процедурную генерацию


Ну. В чём смысл процедурно генерировать настолько кривые и дырявые меши? Процедурная генерация должна следовать чётким правилам и выдавать годный результат, а это грязный прототип, не более.

>разрушаемость


В смысле разделение предмета на части или вырезание дырок в большом объекте? В любом случае это звучит как неуместное использование CSG. После каждого изменения положения примитивов происходит генерация всего меша с нуля, и чем больше примитивов, тем сильнее нагрузка. Алсо вечные дырки и прочие глюки...

>гиперкажуалку про нарезание овощей в CSG


Если овощи будут точно так же мерцать и покрываться рандомными отверстиями, как делают CSG в редакторе - нафиг такое надо...
78 787185
>>87127 (Del)

>Так в TextureButton нет встроенной поддержки регионов, ее и так и так костылить.


В случае с AtlasTexture это называется агрегация, а не костылирование. AtlasTexture берет на себя часть функций, которые касаются конкретно текстур, и позволяет добавить эти функции в любой класс, которому нужен экземпляр класса Texture или одного из его наследников (которым и является AtlasTexture). Нет смысла делать в каждой графической ноде функциональность вывода региона текстуры, если эту функциональность можно выделить в класс текстуры, не так ли?

>Только шейдер займет меньше строчек.


Суть в том, что шейдер тебе нужно написать. А AtlasTexture УЖЕ ЕСТЬ, тебе не нужно ни одной строчки писать. Ты можешь прямо в редакторе создать году TextureButton, в поле текстуры выбрать New AtlasTexture, в ней задать нужную тебе картинку и обозначить регион. Всё! Ни единой строчки кода! Шейдеру ты точно так же будешь назначать текстуру и границы региона, только шейдер тебе сначала нужно написать, сохранить и загрузить, а AtlasTexture встроен в ядро движка, разве это так трудно понять?

>регионы для текстурбаттона


AtlasTexture позволяет задавать регионы текстуры для любых наследников CanvasItem (Node2D/Control).

>Это просто инструмент


Именно. Не нужно применять инструмент не по назначению. Вот представь, ты купил огромный набор различных инструментов, они у тебя разложены по полочкам и занимают место, а ты берёшь плоскогубцы и всё ими делаешь: и гвозди заколачиваешь, и винтики закручиваешь/выкручиваешь, и консервные банки открываешь, и дырки ими сверлишь (вручную вкручивая саморезы), и т.д. ЗАЧЕМ ТЫ ТОГДА ВСЕ ОСТАЛЬНЫЕ ИНСТРУМЕНТЫ КУПИЛ?
79 787243
Сап, анчоусы. Си решеткой в годоте можно уже полноценно кириллить не опасаясь на половине проекта словить минус жизнь? Я просто не люблю питоноподобные языки, а для поддержания практики я бы с радостью кириллил на шарпе. Или же Хуану поебать на си решетку и надо дрочить гдскрипт?
80 787279
>>87231 (Del)

>сбежал из соседнего треда и споришь ради спора


Нет и нет, хотя поспорить я люблю.

>в TextureButton регионов нет, хотя по хорошему ничто не мешает быть встроенным


В который раз повторяю: регионы для использования атласов ВСТРОЕНЫ. Они встроены с помощью ресурса AtlasTexture, который ты можешь воктнуть в любой класс CanvasItem, который запрашивает какую-нибудь текстуру. Тебе не нужно изобретать велосипедную функцию, которая встроена в движок.

>10 строчек кода это не "ни одной строчки"


Во-первых, это только для динамического создания кнопок. Во-вторых, с шейдерами тебе тоже придётся писать кучу "строчек". В-третьих, ну и что? Это же GDScript, а не GLSL. Один раз напишешь и можешь забыть об этом участке проекта, если только в следующей версии движка что-нибудь не поменяют.

>шейдер бла-бла-бла


Да используй свои самописные шейдеры, тебе никто не запрещает этим страдать, просто не советуй писать велосипед там, где он, по факту, не нужен. Ты создаёшь впечатление, что в Godot вообще ничего нет, даже поддержки атласов, на всё нужно шейдеры писать...

>меняют то, как выводится текстура


Зачем применять "большой тяжёлый предмет" для забивания гвоздей, если существует специализированный молоток? Вот у тебя AtlasTexture, в нём параметры, это специализированный инструмент. А в шейдер ты сначала должен программу записать, это универсальный "тяжёлый предмет", которым хоть и можно простые гвозди забивать, но очень неудобно. И потом, у молотка с обратной стороны зачастую есть гвоздодёр (заменить AtlasTexture в инспекторе ноды на что-то другое), а шейдеры ты как выковыривать будешь? Сам же говорил, что шейдер никак с текстурой не связан...

>>87248 (Del)

>ты же не на голом движке делать будешь


Ещё один адепт "в Godot нет ничего встроенного" или это опять ты?

Заметь, это ты недвусмысленно намекаешь, что в Godot нихрена нет и всё нужно с нуля писать или ставить аддонами, а не я. Но внезапно движкосрачером и противником Godot оказываюсь я, хотя я считаю, что всё что нужно в Godot есть из коробки. Странно, не правда ли? На что я трачу время... а ведь мог в это время игру продолжать делать...
80 787279
>>87231 (Del)

>сбежал из соседнего треда и споришь ради спора


Нет и нет, хотя поспорить я люблю.

>в TextureButton регионов нет, хотя по хорошему ничто не мешает быть встроенным


В который раз повторяю: регионы для использования атласов ВСТРОЕНЫ. Они встроены с помощью ресурса AtlasTexture, который ты можешь воктнуть в любой класс CanvasItem, который запрашивает какую-нибудь текстуру. Тебе не нужно изобретать велосипедную функцию, которая встроена в движок.

>10 строчек кода это не "ни одной строчки"


Во-первых, это только для динамического создания кнопок. Во-вторых, с шейдерами тебе тоже придётся писать кучу "строчек". В-третьих, ну и что? Это же GDScript, а не GLSL. Один раз напишешь и можешь забыть об этом участке проекта, если только в следующей версии движка что-нибудь не поменяют.

>шейдер бла-бла-бла


Да используй свои самописные шейдеры, тебе никто не запрещает этим страдать, просто не советуй писать велосипед там, где он, по факту, не нужен. Ты создаёшь впечатление, что в Godot вообще ничего нет, даже поддержки атласов, на всё нужно шейдеры писать...

>меняют то, как выводится текстура


Зачем применять "большой тяжёлый предмет" для забивания гвоздей, если существует специализированный молоток? Вот у тебя AtlasTexture, в нём параметры, это специализированный инструмент. А в шейдер ты сначала должен программу записать, это универсальный "тяжёлый предмет", которым хоть и можно простые гвозди забивать, но очень неудобно. И потом, у молотка с обратной стороны зачастую есть гвоздодёр (заменить AtlasTexture в инспекторе ноды на что-то другое), а шейдеры ты как выковыривать будешь? Сам же говорил, что шейдер никак с текстурой не связан...

>>87248 (Del)

>ты же не на голом движке делать будешь


Ещё один адепт "в Godot нет ничего встроенного" или это опять ты?

Заметь, это ты недвусмысленно намекаешь, что в Godot нихрена нет и всё нужно с нуля писать или ставить аддонами, а не я. Но внезапно движкосрачером и противником Godot оказываюсь я, хотя я считаю, что всё что нужно в Godot есть из коробки. Странно, не правда ли? На что я трачу время... а ведь мог в это время игру продолжать делать...
81 787386
>>87320 (Del)

>террейн


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

>контроллеры персонажей


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

Для большинства игр в Godot есть всё необходимое. Не нужно пугать новичков, что "придётся ставить аддоны, чтобы делать игру".
82 787427
Там это, Godot 4.0 alpha 1 релизнулась!
https://godotengine.org/article/dev-snapshot-godot-4-0-alpha-1
83 787457
ЧЯДНТ?
Пытаюсь при старте скопировать файлы в юзерпапку, примерно вот так:
var dir = Directory.new()
if not dir.file_exists("user://demo1.tres") and dir.file_exists("res://maps/demo1.tres"):
dir.copy("res://maps/demo1.tres", "user://demo1.tres")
В обычном виде (при запуске проекта в годо) всё копируется. А вот после экспорта - перестаёт. Тестировал линукс-версию, браузерную и через вайн. Раньше (на 3.2) такой проблемы не было на том же самом проекте. Пацаны, выручайте!
84 787458
>>87457
сук, какая-то фигня вместо табуляций воткнулась. Ну, надеюсь, и так понятно.
85 787603
Всем привет!
Мне нужно чтобы при нажатии кнопки вызывалась джава скрипт функция из html файла, для этого я использую команду JavaScript.eval, но когда запускаю сцену в браузере и нажимаю кнопку ничего не происходит.
Однако эта же самая функция без проблем вызывается через консоль браузера. Также всё работает если написать код функции прямо в команду JavaScript.eval.
Почему так?
Прикрепляю скриншоты, надеюсь так вам будет понятнее.
86 787630
>>87603
Мне кажется, надо SayHello()
eval эвалюирует код, а не функцию.
87 787649
>>87630
>>87636 (Del)
Спасибо за ответы, ребят, поставил на место скобки и всё заработало. Мне почему-то казалось что я уже так пытался и ничего, лол, очень сильно затупил на этом моменте
88 787650
Как прикрутить сокеты к игре?
89 787691
>>87457

> Раньше (на 3.2) такой проблемы не было на том же самом проекте.


Если раньше такого не было, то это была уязвимость. И её прикрыли. Зачем тебе копировать сцены? Ты делаешь модифицируемую игру? Делай как положено. Через ПАК-файлы. И соответствующие функции для работы с ними.

> В обычном виде (при запуске проекта в годо) всё копируется. А вот после экспорта - перестаёт.


После экспорта в ПАК-файле нет ТСЦН-файлов, они транслируются в байткод, копируются в файлы ТРЕС, а ТСЦН-файлы оставляются как ссылки. Утилита тебе показывает, что файл существует, но существует не файл, а ссылка, игра без проблем переходит по ней и грузит файл из байткода. Но при попытке копирования реально из рес:// копировать нечего.

Не веришь? Экспортни данные в ЗИП и открой его архиватором. Сам всё увидишь.
90 787784
>>87691

>Зачем тебе копировать сцены?


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

>res://maps/demo1.tres


>сцены


TRES это сцена по-твоему? И, кстати, я все сейвы обычно в этом формате делаю, через ResourceSaver, очень удобно, никакой ебли с json-ами.

>res://maps/demo1.tres


>зачем


Затем, чтобы игрок смог открыть демку и посмотреть, например. А потом отредактировать её. А потом и пересохранить без проблем.

Впрочем, ты, несмотря на невнимательность, всё же дал дельный совет, про

>при попытке копирования реально из рес:// копировать нечего.


Значит надо просто загружать эти файлы в перменную, а потом сохранять их в юзерскую папку, получится на одну строчку больше, но не важно, это сделать надо всего один раз при самом первом запуске игры.
91 787806
О, у меня тупой и не очень полезный вопрос созрел.
Предположим, что у меня кнопка на худе дублируется хоткеем на клаве (ну как в любой игре, где есть кнопки на худе). Но при этом клик перехватывается кнопкой, а клава идёт в unhandleld_input. Так вот, мне стало интересно, можно ли как-нибудь просто связать нажатие конкретной клавиши со скриптом этой кнопки, чтобы джва раза не вставать? Или нет, и надо просто наводить порядок в unhandled_input?
1643280181085.jpg25 Кб, 620x432
92 787811
>>87784

> твоя жопоглазость превышает все допустимые пределы


Бля, сорян. Стыдно. Блять.
93 787823
>>87820 (Del)
О, красота. Значит пора как следует перекопать HUD.
94 787893
>>87811
Да ладно, не расстраивайся. Я тоже протупил, и мне стыдно. Знаешь, почему в итоге у меня ресурсы не копировались? Потому что в папке с ними обнаружился файл .gdignore. Хз зачем я его туда положил, но вот удалил, и ресурсы стали без проблем копироваться через dir.copy.
Правда, для копирования превьюх таки пришлось использовать костыль вида (ну, чуть посложнее этого, но идея такая):
var png = load("res://maps/demo1.png")
png.get_data().save_png("user://demo1.png")

Видимо, текстуры таки упаковываются в какие-то ресурсы.
95 787909
Как предсказывать, какие цвета будут в игре? Вообще не понимаю, все настройки перепробовал, а исходный цвет текстуры (16x16, 24bit png) получить не удаётся. Т.е. превью в движке после переключения каких-то опций стало таким как и исходная png-картинка, но в игре деревья выглядят не так, как в блендере. Уже не первый раз сталкиваюсь с таким искажением цвета. Что делать? Как добиться максимально близкого соответствия картинки на экране с картинкой-текстурой? Так было бы намного проще настраивать палитру... Опцию unshaded использовать не хочу, т.к. тогда нельзя будет сделать плавную смену дня и ночи (или я не знаю как).

Алсо зацените миникарту в стиле GTA 5. Круто, правда? Сам сделал, она ещё умеет переключаться в 2D чётко на весь экран. Нужно будет ещё маркеров добавить, но это только когда разберусь с генерацией мира.

Занимаюсь какой-то косметикой вместо важного...
96 787917
>>87911 (Del)

>дефолтное небось


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

>с голубым светом


Ну... а как ещё? Белый что ли ставить?

>цвет своего источника света-солнца


Жёлтовато-оранжевый вроде.

>гипертрофированно


Похоже, только если так. Просто хочется заранее знать, какой цвет будет в движке, чтобы потом не править каждую текстуру по отдельности. Ну, наверное, текстуры должны быть просто похожи друг на друга по оттенкам, а финальный цвет можно настройками окружения поправить...
97 787921
Вот я создаю некий кастомный класс-ресурс, чтобы юзать для хранения данных:
#my_class.gd
extends Resource
class_name MyClass

Дальше пытаюсь заюзать его в другом месте, чтобы удобно было заполнять свойства, типа:
#some_node.gd
export(MyClass) var my_property

Но Годот говорит мне, что так нельзя:

>The export hint isn't a resource type


Ну типа ЧЗХ? Он же прекрасно умеет открывать любые подобные ресурсы в режиме дебага. А так, видите ли, не может. Может, я чего-то не знаю? Кто сталкивался?
98 787942
>>87921

>Он же прекрасно умеет открывать любые подобные ресурсы в режиме дебага. А так, видите ли, не может.


Ресурсы открывает отдельная часть движка. Чтобы экспортнуть кастомный класс, парсер GDScript должен уметь распознавать эти кастомные классы. Щас он видит какой-то левый класс и не знает что с ним делать, потому что не знает, что этот класс - потомок Resource. Ну как-то так короче, нереализованная уже 2 года фича.

Самый логичный на мой взгляд обходной путь - это задать поле типа Resource, а свои ресурсы кидать драг-н-дропом из файловой системы:
https://github.com/godotengine/godot-proposals/issues/18#issuecomment-912576404
Не велика беда, короче, 2 года терпели и ещё потерпим.
99 787955
>>87921

> Но Годот говорит мне, что так нельзя:


Слово экспорт сбивающее с толку. Никакой это не экспорт ниоткуда и никуда. Этим ключевым словом ты создаёшь поля в инспекторе редактора. Чтобы было можно, ты должен добавить в код редактора (да-да, на с++ и пересобрать) функционал для отображения твоих типов. Ты туда пытаешься засунуть кастомный класс, существующий функционал редактора естественно не знает, что с этим всем делать.

> прекрасно умеет открывать любые подобные ресурсы в режиме дебага


В режиме дебага система работает немного иначе, дебаггер висит в дереве и раскладывает все ветви по цепочкам потомков до самых крайних листочков, там уже нет ни классов, ни типов, есть только дерево и поля встроенных типов. Всё это жрёт ресурсы, поэтому при дебаге в общем-то везде выполнение кода идёт несколько медленнее.

Как бы поступил я на твоём месте:

>для хранения данных


Юзал бы встроенные типы. Нужна текстура? Делаю экспортируемое в инспектор редактора поле-текстуру. Нужна строка? Делаю экспортируемую поле-строку. И т.п.

> чтобы удобно было заполнять свойства


Заполнять поля этими ресурсами и/или данными. Внутри кода этими полями инициализируется кастомный класс (если уж такая необходимость имеется).

А вообще, опиши сначала задачу, которую ты решаешь. У тебя типичная форумная ошибка: ты поставил задачу, придумал неуклюжее велосипедное решение, столкнулся с проблемами, и идёшь на форум (в нашем случае ИТТ) не с вопросом, как решить задачу, а с вопросом, как прикрутить третью педаль к твоему велосипеду.
100 787974
>>87955

>Слово экспорт сбивающее с толку. Никакой это не экспорт ниоткуда и никуда.


O RLY?
https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html

>In Godot, class members can be exported. This means their value gets saved along with the resource (such as the scene) they're attached to.



Слово export по сути аналог published из Паскаля:
https://wiki.lazarus.freepascal.org/Published
https://wiki.freepascal.org/Streaming_components

>функционал для отображения твоих типов


Функционал уже есть.
1. Ты можешь открыть, отредактировать и сохранить в инспекторе редактора .tres с ресурсом кастомного типа.
2. Ты можешь создать новый ресурс кастомного типа прямо в поле, выбрав его в гигантском выпадающем списке (на первом экране одни только А..., представь, сколько скроллить до Z...), если в качестве экспортируемого типа указан Resource.

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

Так что ты преувеличиваешь проблему.

>Юзал бы встроенные типы


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

>как прикрутить третью педаль к твоему велосипеду.


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

Да, в его ситуации, возможно, есть и другое решение. Но его он и сам сможет найти, вариантов масса (и все неудобные из-за отсутствия строгой типизации массивов и словарей).
101 787977
>>87974

> отсутствия строгой типизации массивов и словарей


Сам жду её.
102 787979
>>87974

> не имея возможности сгруппировать их по ресурсам


https://www.youtube.com/watch?v=oIzKSXCSdpc
103 787985
>>87977
В альфе 4.0 вроде уже есть типизация массивов:
var a: array[int]

>>87979
Ты разве не понимаешь, что это огромная куча бойлерплейт кода в tool скрипте (который небезопасно редактировать, не сняв tool, т.к. можно сломать редактор), которую нужно повторять для каждого такого класса? Такие тривиальные фичи должны решаться ключевыми словами языка, как тот же export.

Что мешает сделать что-то вроде:
export("category", int) var blablabla
Это было бы просто и удобно.
104 787986
>>87985

> var a: array[int]


Каеф!

> Что мешает сделать что-то вроде:


Ожидаем в ожидании.
Следовать ли рекомендациям по именованию? 105 788113
За много лет работы с Pascal я сформировал привычку называть всё исключительно в PascalCase, в т.ч. файлы и папки. С Linux проблем не имею, потому что не пользуюсь им (пробовал, даже какое-то время было приятно, но постоянные ошибки и многочисленные проблемы заставили вернуться на сравнительно стабильную Windows). Вообще мне кажется PascalCase более естественным что ли... Но недавно узнал, что разработчики Godot рекомендуют snake_case для всех файлов и папок проекта, мол, это избавит от проблем на ОС, которые различают файлы с маленькими и большими буквами. Не понимаю сути проблемы с этими ОС (типа можно опечатку в коде допустить, которую проигнорирует Windows, но на которой навернётся -nix?), но меня раздражает, что стандартные файлы Godot в snake_case, а мои в PascalCase. Поэтому решил постепенно всё переименовать и переделать код в рекомендуемый вид...

Но, блин, столько всего теперь переделывать. И одно только переменование папки вызовет кучу проблем с поиском "пропавших" файлов, а делать это через Godot неудобно - он постоянно какие-то глюки ловит, приходится переоткрывать все файлы или проект в целом, так что лучше уж из Проводника всё сделать. Я уже начал переименовывать, но теперь задумался - а стоило ли?..
106 788124
>>88119 (Del)

>андроид (там линукс


Знаю, яжпрограммист. Даже хеллоуворлдил на Java под Android.

>в коде напишешь load("myscene.tscn")


Собсна возникает вопрос: как такое может произойти? Я всегда внимательно слежу за тем, чтобы все имена были правильными. Даже на Pascal соблюдаю регистр, хотя компилятору пофиг, как ты будешь записывать переменные, для него hello и HELLO - одно и то же. Ну а в случае файлов - ссылку на них проще всего получить драг-н-дропом из окошка файловой системы, если нужен абсолютный путь, тут уже невозможно ошибиться.

Ну ладно, не важно, я уже решил всё переименовать (прокрастинация такая прокрастинация, лишь бы не делать то, что реально нужно для развития прототипа).
107 788127
>>88124
Проблемы могут возникнуть после всяких там операций с файлами типа копирования в другую файловую систему или архивации, после которых твой ВерблюжийРегистр превратится в строчный. Например.
Или ещё в случае, если кто-то другой захочет добавить/отредактировать твои ресурсы, при этом работая на регистро-чувствительной системе, вот там вообще ад начнётся, я однажды пробовал из-под линукса моддить виндовые игры, никому такого не пожелаю.
Или, например, ты вдруг будешь работать в команде, такое тоже случается, причём иногда непредсказуемо.
108 788133
>>88124
У меня такая проблема была на моём первом ТВГ. Аудиофайлы были с большими буквами и собранная под линукс игра шла без звука. Благо у всех стоит виндовс и никто этого не заметил. Впрочем, мне это не помогло и я всё равно занял место где-то в конце.
109 788138
>>88124

>яжпрограммист


>>88113

>Pascal


Ты определись, кто ты.
110 788139
>>88119 (Del)

> ты назоваешь файл MyScene.tscn а в коде напишешь load("myscene.tscn")


Так это ведь два разных файла получается. Почему это не должно быть ошибкой?
111 788153
Я второй день пытаюсь кастомизировать тему оформления, и у меня горит. Тыкаю во все элементы подряд, заполняю цвета и фоны, но зачастую то, что надо, не меняется, зато меняется то, что не надо. Допустим, тыкаю в TextEdit, но на ричтексте это никак не отражается. Или вот поменял где-то фон, уже забыл где, а у меня панель справа (которая вообще-то годотская встроенная, а не моя внутриигровая) приобрела тот же фон; и теперь я хз как это убрать, а убрать надо, потому что он фон светлый, тема годота тёмная, шрифты светлые - на панели редактирования элементов не видно подписи к этим элементам.
Кароч. У меня два вопроса к уважаемому благородному сообществу:

1. Где найти схему, какой элемент от какого наследует свойства?
2. Как оформить фоны в виде чего-то типа NinePatchRect?

По поводу второго. Вот есть текстовое поле. У него есть границы и заполнение. Хочу сделать неровное такое оформление, типа от руки нарисованное на зернистой бумаге. То есть, это должна быть текстура. Но она должна адаптироваться под любые размеры поля. Если я просто загружаю текстуру, она всрато растягивается и всё. А уж заставить это тайлиться вообще никакими плясками не удалось (про опцию в импорте знаю).
памагити.
112 788161
>>88141 (Del)
>>88142 (Del)
Ох, какое же говно этот ваш Шиндоус.
113 788174
>>88153
УМВР.
Что тебе посоветовать? Читай документацию. Не буду же я её сюда репостить.
114 788177
>>88174
Ссылку дай на страницу в документации, где ты видел ответы на мои вопросы.
inb4 наследование свойств совпадает с наследованием классов: нет, не совпадает.
115 788184
>>88153

> Где найти схему, какой элемент от какого наследует свойства?


https://docs.godotengine.org/ru/latest/tutorials/ui/gui_using_theme_editor.html#creating-a-theme

> Как оформить фоны в виде чего-то типа NinePatchRect?


https://docs.godotengine.org/ru/latest/classes/class_styleboxtexture.html#class-styleboxtexture
116 788218
>>88184

>какой элемент от какого наследует свойства?


Так и где здесь?
На самом деле проблема в том, что некоторые элементы разделяют между собой общие ресурсы-свойства. Поменяешь одно - поменяются все сопричастные. Это не совсем наследование. И вот в том-то и вопрос: какие ресурсы у каких элементов общие?

А по второму пункту аригато, я почему-то думал, что там просто ImageTexture.
1643563011312.png41 Кб, 964x541
Ля какой я у мамы дизайнер 117 788258
Сделал сапёр для инопланетян с глазами.
Играя в этот сапёр инопланетяне вырывают себе глаза. Так и победим их! Хитро, а?
118 788271
Попробовал таки lua-расширение для Годота. И я в печали. Там не работает дебаг. Написал myvar.myfunc() вместо muvar:myfunc(), игра вывалилась молча, ничего не сказав в консоль. А это у меня самая частая ошибка, которую ещё и своими глазами отыскивать трудно, поди найди эту сраную точку. Без дебаггера никак. Жаль, я очень люблю луа.
Ну ладно. Продолжу на гдскрипте. Может, к концу недели выкачу на суд анонимуса первые демо-материалы.
119 788328
Рубрика «больше тупых вопросов богу тупых вопросов».
Есть ли пристойный способ двигать камерой/цеплять камеру к юниту, не перебрасывая её постоянно по дереву туда-сюда? Всё-таки к ней обычно худ прибит, один неудачно оставленный относительный путь, и при перескоке от фокуса к свободной камере может случиться небольшой адок.
Хотя по-моему у меня дерево камеры и дерево карты, где все, общаются только через указатели и сигналы, и бояться нечего.
120 788334
>>88328
Можешь просто устанавливать куррент камеру. Не понятно чем тебе обычный вьюпорт так нагружает систему.
121 788337
>>88328

>цеплять камеру к юниту


Я вижу три пути.

Метод грубой силы: ставишь каждому юниту отдельную камеру, при необходимости вызываешь у неё make_current(), а чтобы вернуться на предыдущую - clear_current(). Проблемы: если юнитов тысячи, будут тысячи лишних нод камер; переключение мгновенное, сгладить переход невозможно без дополнительных костылей. Преимущества: для простой игры самый быстрый и удобный способ.

Камера-водитель/пассажир: помещается внутрь юнита через add_child(), после чего автоматически следует за юнитом. Проблемы: как и в предыдущем случае, невозможно сделать плавное переключение, потому что камера за один кадр перескакивает из предыдущего юнита в новый. Преимущества: всего одна камера, реализация не сильно сложнее предыдущего способа.

Умная камера: передаёшь ей ссылку на юнита, за которым она должна следить, и дальше она в методе _process() сама смещает себя к нужному юниту с заданной скоростью и задержкой, сама вращает себя соответственно направлению взгляда юнита и так далее. Проблемы: нужно будет немного покопаться в формулах, которые в 3D будут ещё сложнее; юниту сложнее получать информацию из камеры. Преимущества: плавное перемещение всего одной камеры без отключения от сцены, камера может переключаться на абсолютно любой объект сцены (наследника Spatial или Node2D) без дополнительного кода в этом объекте, т.к. камера автономна. Если что, регулярное обновление позиции в _process() вообще не проблема, ты же так и так её каждый кадр мышкой теребишь.

>к ней обычно худ прибит


Лол, зачем? В 2D худ должен быть на отдельном CanvasLayer отдельно от камеры, иначе его расколбасит зумом камеры. В 3D худ может быть вообще где угодно в дереве сцены, т.к. рендерится независимо от пространственных нод (у меня худ грузится как синглтон - видим на экране даже без камер в сцене).

>неудачно оставленный относительный путь


Кем оставленный? Юнит должен сам забрать себе камеру или сам отдать её другому юниту. Хотя, в условиях стратегии лучше чтобы камера была умной и жила полностью независимо от юнитов. В моём примере выше, если юнит умрёт и будет удалён (ссылка сломается), камера просто остановится на одном месте и будет ждать других приказов игрока, тогда как камеру в потомках юнита нужно кому-то вернуть перед уничтожением юнита. Просто делай проверку (не уверен, правильно ли, раньше так не делал):
if target is Node: # цель существует, следим за ней
121 788337
>>88328

>цеплять камеру к юниту


Я вижу три пути.

Метод грубой силы: ставишь каждому юниту отдельную камеру, при необходимости вызываешь у неё make_current(), а чтобы вернуться на предыдущую - clear_current(). Проблемы: если юнитов тысячи, будут тысячи лишних нод камер; переключение мгновенное, сгладить переход невозможно без дополнительных костылей. Преимущества: для простой игры самый быстрый и удобный способ.

Камера-водитель/пассажир: помещается внутрь юнита через add_child(), после чего автоматически следует за юнитом. Проблемы: как и в предыдущем случае, невозможно сделать плавное переключение, потому что камера за один кадр перескакивает из предыдущего юнита в новый. Преимущества: всего одна камера, реализация не сильно сложнее предыдущего способа.

Умная камера: передаёшь ей ссылку на юнита, за которым она должна следить, и дальше она в методе _process() сама смещает себя к нужному юниту с заданной скоростью и задержкой, сама вращает себя соответственно направлению взгляда юнита и так далее. Проблемы: нужно будет немного покопаться в формулах, которые в 3D будут ещё сложнее; юниту сложнее получать информацию из камеры. Преимущества: плавное перемещение всего одной камеры без отключения от сцены, камера может переключаться на абсолютно любой объект сцены (наследника Spatial или Node2D) без дополнительного кода в этом объекте, т.к. камера автономна. Если что, регулярное обновление позиции в _process() вообще не проблема, ты же так и так её каждый кадр мышкой теребишь.

>к ней обычно худ прибит


Лол, зачем? В 2D худ должен быть на отдельном CanvasLayer отдельно от камеры, иначе его расколбасит зумом камеры. В 3D худ может быть вообще где угодно в дереве сцены, т.к. рендерится независимо от пространственных нод (у меня худ грузится как синглтон - видим на экране даже без камер в сцене).

>неудачно оставленный относительный путь


Кем оставленный? Юнит должен сам забрать себе камеру или сам отдать её другому юниту. Хотя, в условиях стратегии лучше чтобы камера была умной и жила полностью независимо от юнитов. В моём примере выше, если юнит умрёт и будет удалён (ссылка сломается), камера просто остановится на одном месте и будет ждать других приказов игрока, тогда как камеру в потомках юнита нужно кому-то вернуть перед уничтожением юнита. Просто делай проверку (не уверен, правильно ли, раньше так не делал):
if target is Node: # цель существует, следим за ней
122 788339
>>88337

>юниту сложнее получать информацию из камеры


Перемудрил немного. На самом деле ничего сложного: поскольку камера в сцене гарантированно одна, она может быть реализована как синглтон и, следовательно, все юниты заранее знают о камере, им остаётся только узнать, за кем следит камера, но об этом может сообщать юниту сама камера в момент переключения. Также камера может передавать юниту ссылку на себя, если предполагается возможность наличия более одной камеры (пример: мультиплеер с разделённым экраном).

Эх, нужно в моём проекте такую камеру запилить. А то начинал проект два года назад и изначально сделал всё на make_current(), но моей игре (а-ля ГТА) нужна намного более свободная камера, не зависящая от персонажа и других объектов...
123 788345
>>88328

>Есть ли пристойный способ двигать камерой/цеплять камеру к юниту,


RemoteTransform[2D]

>к ней обычно худ прибит,


Плохая идея, лучше использовать CanvasLayer.
124 788347
>>88345

>RemoteTransform[2D]


Придётся повесить эти ноды на каждого юнита? Или задавать корневую ноду этого класса? И потом ещё каждый раз переключать их. Или перетаскивать эту ноду с юнита на юнит... И опять же никакой плавности. По-моему, мой вариант более гибкий: >>88337

>Умная камера: передаёшь ей ссылку на юнита, за которым она должна следить, и дальше она в методе _process() сама смещает себя к нужному юниту с заданной скоростью и задержкой, сама вращает себя соответственно направлению взгляда юнита и так далее.


- намного больше контроля и никаких лишних нод.

>лучше использовать CanvasLayer.


А для 3D игры нужно?
125 788354
>>88347

>Придётся повесить эти ноды на каждого юнита?


Лучше, чем вешать камеры. Хотя есть версия, что выключенная камера потребляет ресурсов не больше, чем базовая Node2D без скрипта, то есть почти никак.

>И опять же никакой плавности.


Плавность включается в настройках камеры. В момент отключения одного трансформа и включения другого камера с включённым smoothing'ом плавно переезжает на него. Хотя я хз, как это в тридэ работает.

>намного больше контроля и никаких лишних нод.


Намного больше мозгоебли. И имхо лучше лишние ноды, чем лишний _process. Но, конечно, смотря сколько их. В моём нынешнем проекте процесс есть вообще ТОЛЬКО в кинематиках. Нигде больше. Просто в Годоте и без того много всякой умной автоматизации, и она реализована на плюсах, что в разы быстрее, чем если прописывать гдскрипт в _процессе.
И да, кстати. Если уж всё-таки необходимо, то для камеры (да и вообще почти для всего) имеет смысл использовать _physics_process. Он реже тикает.
126 788355
>>88347

>А для 3D игры нужно?


Вопрос к анонам, шарящим в 3д. Я не шарю.
127 788356
>>88345
Ну я имею в виду, что к камере прикручен CanvasLayer, а на ней худ.
Был CanvasLayer, потому что кнопки поверх него внезапно не захотели работать, и я нагуглил, что это пока не пофикшенный баг. Сейчас там просто какая-то нода, но, естественно, не прямо на камеру навесным монтажом, всё можно переделать.
128 788372
>>88354

> в Годоте и без того много всякой умной автоматизации, и она реализована на плюсах, что в разы быстрее, чем если прописывать гдскрипт в _процессе


Именно так. Почему-то никто из отвечающих не упомянул класс InterpolatedCamera, у которого кокрастоке на плюсах реализован функционал из этого поста:
>>88337

> Умная камера: передаёшь ей ссылку на юнита, за которым она должна следить, и дальше она в методе _process() сама смещает себя к нужному юниту с заданной скоростью и задержкой, сама вращает себя соответственно направлению взгляда юнита и так далее.

129 788376
>>88372

>InterpolatedCamera


КЕК ЛОЛ Д Е П Р Е К О Л
ЛОЛ КЕК Д Е П Р Е К Е Т
https://docs.godotengine.org/en/stable/classes/class_interpolatedcamera.html

>Deprecated (will be removed in Godot 4.0).


https://github.com/godotengine/godot/issues/42970

>Please provide a plug-in replacement for InterpolatedCamera


>That's done already :)


http://godotengine.org/asset-library/asset/739
https://github.com/godot-extended-libraries/godot-interpolated-camera3d/blob/master/addons/interpolated_camera_3d/interpolated_camera_3d.gd

>_process



>>88354

>лишний _process


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

>_physics_process


Для камеры это неприемлемо. Если у тебя физика, скажем, 50 тиков в секунду, а у пользователя монитор 240 Гц, то твоя камера будет неприятно дёргаться. Камера всего одна и от неё во многом зависят ощущения от игры, поэтому экономить на ней нельзя.

В целом, если что-то должно обновляться визуально - оно должно быть в _process, иначе будет заметно лагать на любом экране, у которого герц больше 60. Да и глупо это, привязывать визуальные процессы к частоте физического движка - а что, если ты решишь снизить частоту физики, потому что она тебе не больно-то и нужна (в тех же стратегиях с видом сверху)?

>Плавность включается в настройках камеры


>камера с включённым smoothing


В 2D да, в 3D такой функциональности у камеры нет. Думаю, это связано с тем, что сами движения в 3D могут быть разными; в какой-то ситуации камера не должна вращаться, в какой-то должна поворачиваться в сторону цели и только потом с ней сближаться и так далее. Т.е. универсальной галочки "смузинг" в 3D не сделать.
1643625381875.jpg23 Кб, 229x190
130 788378
>>88376

> Deprecated


Ебало моё представили? Если нет, я помогу, пикрелейтед.
Но вообще же авторы своевременно аддон выпустили, так что для проектов на трёшке можно продолжать её юзать. А на четвёрку всё равно проекты мигрировать будет НАСТОЛЬКО сложно, что замена встроенного класса на аддон там будет меньшей из проблем.
slow.jpg46 Кб, 400x400
131 788389
>>88378

>пикрелейтед


Не парься, я за джва года ленивого ковыряния только теперь обратил внимание на потомки Camera. Кстати, ClippedCamera тоже удалили, но в документации она даже не помечена как deprecated:
https://github.com/godotengine/godot/pull/53354
https://docs.godotengine.org/en/stable/classes/class_clippedcamera.html

>аддон выпустили


Вот только он не является полной копией, нельзя просто закинуть в проект и заменить им InterpolatedCamera.

>мигрировать будет НАСТОЛЬКО сложно


Да ладно. Подумаешь, немного синтаксис изменился, немного названия поменялись, несколько классов перекинулись функциями друг в друга... Не думаю, что придётся что-то кардинально менять.
1643643746000.png46 Кб, 515x539
132 788440
Сап, годач!
Это я!
Хочу научиться распределять мины по полю при помоши симпл-нойза. А то чистый рандом даёт большую кучность мин рандомно опять же. Научи, грамотный анон, плиз.
133 788443
>>88440

>симпл-нойза


В мануале пример кода есть.
https://docs.godotengine.org/en/stable/classes/class_opensimplexnoise.html

>чистый рандом даёт большую кучность мин


Ну так симплекс даст тебе ещё большую кучность, чем чистый рандом. Потому что симплексный шум - это градиентный шум. Он создаёт градиенты между рандомными точками в пространстве.

Пример 1D шума:
Рандом: 2 6 3 -7 8 3 0 9 -2 8 3 -4 1 6 0
Градиент: 3 2 1 2 3 4 3 2 3 2 1 0 -1 -2 -1

Обычно, градиентный 2D шум используют для того, чтобы сгенерировать некие замкнутые области на плоскости. Для этого выбирают некое число, и затем выделяют все точки, в которых значение шума выше (или ниже) этого числа. Скажем, все точки с шумом ниже 0 будут под водой, а все точки выше 50 будут иметь каменистую текстуру. Аналогично можно использовать 3D шум для генерации подземных пещер и т.п.

В твоём случае я могу предложить такое решение. Сейчас ты, наверное, просто выбираешь рандомную точку между 0 и map_size, и затем ставишь в эту точку мину, верно? Попробуй разделить карту на квадраты, и затем для каждого квадрата генерировать ограниченное количество мин. Если в одном квадрате может быть только одна мина, в худшем случае получится пачка из 4 мин, но это будет происходить тем реже, чем крупнее квадраты. Выведи параметры генератора в интерфейс редактора и экспериментируй, меняя размер квадратов и число мин в каждом квадрате, потом зафиксируешь в коде лучшее значение.
1643648547987.png47 Кб, 961x537
134 788450
>>88443

> симплекс даст тебе ещё большую кучность


Смотря какой период. Я уже колдую над примером из доков самостоятельно. Вот пока такие результаты. Но тут проблема в том, что я не смогу задать количество мин. Придётся в два прохода. Сначала по результатам нойза накидать мин, пока лимит не выйдет, либо пока отмеченные нойзом клетки не закончатся. Если после первого прохода лимит мин не исчерпан, то докидать оставшиеся мины рандомом.

Либо вообще хуй забить. И так сойдёт.жпг
135 788453
>>88443

> Сейчас ты, наверное, просто выбираешь рандомную точку между 0 и map_size, и затем ставишь в эту точку мину, верно?


Верно.

> Если в одном квадрате может быть только


Бля. Погоди. У меня же есть ссылка на соседей в каждой ячейке! Бля-бля-бля! Гениально! Ща погоди, выкачу решение!
136 788454
>>88453
Вот так! На скрине классический хард-мод классического сапёра. На втором скрине код генератора. У меня даже метод был подходящий. Строка 165.
Единственный нюанс, если мин много, то генератор может зависнуть, потому что будет очень долго бегать по итерациям.
137 788457
>>88454
А как вам такой вариант? Не слишком ли просто получается? Мины вообще рассеяны.
Каждую тысячу итераций лимит мин, которые могут быть рядом, увеличивается на 1. Таким образом происходит защита от дедлока.
138 788459
>>88457
С таким распределением резко возросла сложность. Оказалось, за счёт кучностей мин, были так же и пустоты, неплохо помогающие, чтобы подходить к минам с разных сторон. Теперь пустот нет и игра неизбежно приходит к печальному концу.
rikoshet 2022-02-01 00-22-31.png1,7 Мб, 1920x1080
139 788488
Годаны, я тут старый проект немножечко перепилил. Не то чтобы он какой-то крутой (за год на итче собрал полторы сотни просмотров), но с оригинальной концепцией. Я ща посмотрел на сапёр-куна и подумал, что надо бы хотя бы скрин вкинуть. Тред, что скажешь?
140 788496
>>88488
Без текстового описания или хотя бы видео геймплея ничего не понятно. Выглядит как какой-то редактор уровней, по которым потом какой-то мячик движется, но непонятно, что делают все эти треугольники и в чём суть головоломки (если она здесь есть).

Графика хорошая, это сканы бумаги? Я сначала хотел написать, зачем ты фотку своей тетрадки вместо игры выложил)
141 788531
>>88488
Дак а чой делать нада-таа?
b.png43 Кб, 190x190
142 788634
>>88548 (Del)

>про лазерный луч


Больше похоже на мячик, отскакивающий от препятствий (и изменяющий свои свойства?). Но назначение всех этих цветных треугольников непонятно.

Проблема многих таких головоломок в отсутствии интуитивности. Вместо решения головоломки приходится запоминать и вспоминать, что же все эти плитки означают/делают...
143 788653
>>88496

>Графика хорошая, это сканы бумаги?


Йеп
>>88542 (Del)

>напоминает игры в которые 30 лет в тетрадках сами выдумывали


Ты вот щас чётко уловил суть.

Ладно, крч. Тредику спасибо за помощь, я почерпнул некоторые полезные мелочи, просто читая здешние обсуждения.
https://youtu.be/NY3kiWOhp0g

В любом случае я по следующей игре буду открывать тред, так как она помасштабнее, да и в другом жанре. Но графониум в целом такой же будет вручную нарисованный. Только когда допилю до состояния, когда будет что показать.
144 788661
>>88653
Пинбол? Пинбол!
external-content.duckduckgo.com.jpg269 Кб, 1502x845
145 788679
>>88653
Смотри, ты так до 12>6 дорисуешься.
4.0.png7 Кб, 480x223
146 788724
>>88707 (Del)

>приходится через командную строку


В официальном архиве есть файл _console.cmd - запускаешь его и будет тебе консоль. Можешь свой вариант написать, в интернете есть руководства по batch scripts. А вообще, не вижу смысла в отдельной консоли. В неё выводится всё то же, что выводится в консоль самого Godot, а потом сохраняется в файл

>%appdata%/Godot/app_userdata/имя_проекта/logs/godot.log


Я с самого начала использования Godot консоль отключил и за два года в ней не нуждался.
147 788763
>>88707 (Del)

> консольку убрали


Разве там нет пункта в настройках, который отвечает за показ консольки?
148 788830
Решил всё таки переписать сапёра на тайлмап (чтобы воочию сравнить производительность) и возникла задачка, над которой, думаю, будет интересно поразмышлять анону.
Сейчас, решение на кнопках, сделано втупую-влоб, путём запихивания стейтмашины в каждую кнопку-префаб. При клике на кнопку срабатывает её колбэк обработки кликов кнопки и переключает стейт сообразно нажатой клавише. Всё удобно, логично. Игровое поле является массивом самих этих кнопок-префабов. При создании их, происходит формирование ссылок на соседей каждой кнопки. В дальнейшем кнопка работает с этим массивом соседей.

Теперь. Кнопок нет. Колбэков нет. Есть один объект тайлмап, в котором можно через колбэк инпута выяснить, над каким тайлом щёлкнулась мышка. Нужно теперь повторить предыдущую систему.

Я предлагаю следующее.
1. Беру скрипт кнопки,
2. Меняю наследование на от Object, потому что в дерево сцены я эти стейтмашины помещать не буду, не вижу смысла.
3. Вырезаю оттуда всё, что было связано с манипуляциями текстурой кнопок.
4. Добавляю манипуляции тайлами подаваемого на вход тайлмапа.
5. При создании массива таких объектов в них так же создаются ссылки на соседей.
6. В тайлмапе задаю первоначальный вид поля нулевым граунд-тайлом.
7. Получаю массив get_used_cells()
8. Создаю массив объектов вышеописанного типа, каждый из которых соответствует координатам ячейки из предыдущего пункта.
9. Далее подгоняю существующую логику под новые условия. Придётся часть логики заменить.

Какие могут быть подводные камни? Не слишком ли я усложняю? Может мне отказаться от массива объектов-хелперов и сделать иначе? Но всё равно где-то инфу о количестве и координатах мин хранить придётся, так почему бы не совместить это с функционалом стейтмашины? Анон пиливший сапёра ранее, как решил вопрос ты?
146521227-0c526dbb-4a66-4b18-9633-7b36bb960400.png47 Кб, 585x804
149 788841
>>88812 (Del)

>Там намного более подробный отчет.


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

>Только зачем вдруг понадобилось заводить отдельный файл? Чем мешала галочка или параметр запуска?


Судя по всему, для унификации с никсами:
https://github.com/godotengine/godot/pull/55987
https://github.com/godotengine/godot/pull/56012

>With these changes, console behavior on Windows should be the same as on Linux and macOS:


>When editor is started from the console (or by another process with active console), output will be redirected to the parent console (including output from the running projects).


>When editor is started from the GUI (shortcut, Windows Explorer, etc.), no console is opened.



Также:

>In both cases behavior will be similar to old. The only difference, terminal won't auto close after exiting/crashing the editor.


Потому что при запуске из cmd.exe процесс Godot дочерний, а раньше консоль запускалась как дочерний процесс самого Godot. Теперь консоль остаётся открытой в случае падения Godot.

>заводить отдельный файл


Необязательно, см. пикрил.

Странно что ты интересуешься продвинутыми логами, но при этом в первую очередь побежал жаловаться на двач, а не искать информацию в официальном репозитории) Повезло, что я наткнулся на эти странички какое-то время назад и не забыл об этом...
150 788843
>>88830

>Беру скрипт кнопки


Да выкинь ты уже эти кнопки, лол, и пиши с нуля.

>количестве и координатах мин хранить придётся


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

>стейтмашина


А она у тебя для чего используется?

Вообще ты всё как-то сильно усложняешь. Независимо от способа рендеринга поля, его логика заключается в работе с двумерным массивом ячеек. Всё. Как ты эти ячейки рендеришь - кнопками, тайлмапом, вручную в _draw() - значения не имеет. Банальный паттерн MVC, где модель - двумерный массив, а роль вьювера и контроллера могут выполнять разные компоненты движка.

https://en.wikipedia.org/wiki/Model–view–controller
новая мини-карта.png78 Кб, 786x500
151 788844
>>88830 >>88843
https://ru.wikipedia.org/wiki/Model-View-Controller

>Основная цель применения этой концепции состоит в отделении бизнес-логики (модели) от её визуализации (представления, вида). За счёт такого разделения повышается возможность повторного использования кода. Наиболее полезно применение данной концепции в тех случаях, когда пользователь должен видеть те же самые данные одновременно в различных контекстах и/или с различных точек зрения.



Я это применил к игровому миру в целом. Сначала генерирую и сохраняю абстрактную модель, потом могу отображать её как в 3D (игровой мир), так и в 2D (карта/мини-карта), а потом можно будет прикрутить разные способы воздействия (изменения мира). Так вот от особенностей Godot зависит только представление/отображение мира, а этап генерации, хранения и изменения абстрактной модели мира вообще от движка никак не зависит. Короче, это... абстрагироваться надо почаще, вот.
152 788859
>>88843

> Банальный паттерн MVC


Вот я и привожу старый код к МВЦ.

> Да выкинь ты уже эти кнопки, лол, и пиши с нуля.


Выкинул:
>>88830

> Меняю наследование на от Object


>>88843

> А она у тебя для чего используется?


Как только постигнешь суть стейтмашин, всё делаешь на стейтмашинах.
external-content.duckduckgo.com.jpg52 Кб, 1280x720
153 788878
>>85715 (OP)
Пришло время чтобы поставить точку в борьбе этих двух фэндомов. Что всё-таки лучше, делать декремент отдельной переменной внутри process (то есть писать что-то типа period -= delta; if period < 0: do_something), или серить повторяющимися таймерами по всему дереву?
А если process будет создан только для этой цели, и таймер позволит от него избавиться?
1643824680833.png13 Кб, 242x234
154 788880
>>88878
Хуан серит таймерами и ты так делай.
155 788882
>>88880
Хороший аргумент. Но Хуан всё-таки заинтересованное лицо, он эти таймеры по ночам кодил, не выкидывать же их?
156 788883
>>88878
Ну смотри. Лишний _process - это постоянно работающий вызов, который будет каждый тик залезать в гдскрипт и пытаться его обрабатывать. А таймер опрашивается из плюсового кода, что как бы гораздо быстрее.
И да. Всё это имеет значение, если у тебя МНОГО таких нод. Если одна - забей и делай так, как нравится.
Кстати. Вероятно, на шарпее в этой ситуации соотношение может поменяться.
157 788914
М-даа. Полтора года прошло, а нелепые проблемы 2д-анимации как были, так и остались.
1. Из нод-костей всё ещё не делаются жёсткие ИК-цепочки (как это IK вообще переводится?). Хочешь анимировать мышкой без заёбов с растяжением костей - делай иерархию нод и создавай из них пользовательские кости. Я хз почему так, но это тупо.
2. Угол поворота при выстраивании пользовательских костей иногда выставляется неадекватный, под тысячу. Автоврапа угла поворота нет, из-за чего после запуска анимации персонаж начинает танцевать лютый флексинг, пытаясь провернуть конечность два-три оборота и обратно.
3. При нажании "вставить ключ (существующие дорожки)" вставляются ключи не для всех существующих дорожек. Хз почему и чем это определяется.
4. Отразить анимацию по горизонтали вообще никак нельзя. Только вручную заново делать в обоих направлениях. Что на фоне предыдущих двух ошибок, сильно замедляющих процесс создания анимаций, вообще выбешивает. Ну, то есть, можно задать у корневой ноды трансформ -1 по иксу, но это может привести к багам с физикой и другими дочерними нодами.

Ну штош. Будем работать с тем, что есть.
158 788918
>>88878
Если не делать никаких стресс-тестов...

Собственный код в _process или в _physics_process гарантирует тебе порядок и частоту выполнения. При этом вряд ли там такие уж большие затраты, у меня присвоение значений в цикле тысячам переменных в двумерном массиве занимает пару миллисекунд на процессоре 2007 года, одно вычитание вообще ничего не сделает. Также такой код будет прямо в скрипте, т.е. работать без необходимости настраивать сцену, что вдвойне полезно, когда делишься куском кода в интернете.

Нода "таймер" позволяет цеплять таймер не только к кадрам, но и к времени бездействия (idle). Как это работает - не знаю, но по идее, если игра сильно загружена, idle-таймер должен опоздать на какое-то время, что выгодно для процессов, которые не обязательно выполнять в строгие интервалы времени. Также таймер имеет события, обработчики которого можно повесить сразу в нескольких скриптах - т.е. на срабатывание одного таймера могут реагировать сразу несколько разных нод. Ну и, конечно, отдельная нода удобна дизайнерам, которые не хотят копаться в коде. Но если ты будешь создавать очень много таймеров, то ты быстрее упрёшься в количество нод, вызывающее лаги дерева сцены. Т.е. если у тебя планируются тысячи НПЦ с независимыми таймерами, лучше сделать один общий таймер или заменить своим кодом - нужно тестировать, что будет выгоднее, но что угодно будет выгоднее тысяч лишних нод.
159 788920
>>88914

>как это IK вообще переводится?


Inverse Kinematics - инверсная кинематика.
https://ru.wikipedia.org/wiki/Инверсная_кинематика

>персонаж начинает танцевать лютый флексинг


Не баг, а фича.

>можно задать у корневой ноды трансформ -1 по иксу, но это может привести к багам с физикой и другими дочерними нодами.


Делаешь физику и другие штуки отдельно от анимации
@
Изменение анимации не вызывает баги физики и других штук

В чём вообще проблема?
- персонаж
- - физика
- - другие штуки
- - анимация - переворачивай это, а не "персонаж"
- - - скелет
160 788933
>>88920

>Делаешь физику и другие штуки отдельно от анимации


С точки зрения логики да, это идейно верный подход.
Но особенности работы ноды анимации в Годоте подталкивают к тому, чтобы именно она управляла всеми остальными штуками. Я уже пробовал и так и сяк и эдак и вот так, пришёл к однозначному выводу: когда анимация не управляет всеми прочими процессами, это получается а) несинхронно, б) костыльно. Годотская нода анимации слишком ультимативна и удобна, позволяет сэкономить кучу кода и вообще имба; имхо, это одно из самых удачных решений в движке.
Тащемта у меня сейчас схема один в один совпадает с твоей иллюстрацией. Но это не сильно помогает, потому что при зеркальном отражении должен меняться ещё и порядок отрисовки частей, а ещё сами спрайты тоже должны быть другие; ну и ещё куча деталей помельче.
161 788973
>>88914

> Из нод-костей всё ещё не делаются жёсткие ИК-цепочки (как это IK вообще переводится?)


Если бы я не знал, что такое ИК (инфракрасный пульт?) то я бы тоже не понимал, как этим пользоваться.
Але-ОП 162 789002
Сапёр на тайлмапе.
Что я могу сказать здесь? Код успешно оторван от зависимости к кнопкам, но теперь он стал зависеть от тайлмапа. Я не смог реализовать настоящий МВЦ. Слишком туп, наверное.
1643900828479.png91 Кб, 729x589
163 789069
>>89029 (Del)
А, ну тогда у меня эта модель уже есть. Собсна массив field и есть эта модель, хранила объект, как показано на предыдущем скрине, но я понял, что объект там смысла не имеет и заменил на словарь. Комменты на скрине.
164 789146
>>88973
Если знаешь суть предмета, но не знаешь его название, можешь ли ты им пользоваться? А если наоборот, знаешь название, но не знаешь суть?
165 789148
>>89146
Во втором случае помогают поисковики, а в первом можно спросить живых людей, и у тебя появится вся полнота информации.
166 789164
>>88914
Парень, что-то не нравится - допили сам. В этом и прелесть Годота.
167 789180
>>89164

>В этом и прелесть Годота.


Прелесть Годота в том, что это готовый движок с полным набором функций, свободный от корпоративного коммерческого говна. А "сделай сам" это Love2D, например.
>>89163 (Del)

>Также, по 4-м пункту, есть еще другие решения, например


Чевоблять? Пространство и время не путай.
>>89146

>а в первом можно спросить живых людей


Ну так вот, я спросил живых людей, как расшифровывается IK, суть которой я давно знаю, и теперь у меня есть вся полнота информации.

>>89160 (Del)

>Вполне можно наскриптовать свой IK и там сделать chain lock


У меня есть два велосипеда: один работающий, другой сломанный. Чем изобретать третий, я просто поеду на работающем.
Тем более что вообще-то мой нынешний способ даже описан в официальном туториале.

>Опять же, может быть это несложно исправить своим скриптом?


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

>берет анимацию и разворачивает ее в массиве.


Вот тут не всё так просто. Нельзя просто так взять и инвертнуть всю анимацию, потому что она построена на скелете, а у скелета иерархия трансформаций. Я ною об отсутствии такой функции в движке, потому что сам хз, как её реализовать, мой матан не справляется. Хотя уже, кажется, нашёл работающее обходное решение.
168 789187
>>89182 (Del)
Чел, ты... как бы помягче сказать... протрезвей и перечитай, какая изначально задача стояла:

>4. Отразить по горизонтали

wtf.png2 Кб, 208x83
169 789255
Мне кажется, или я нашёл баг в 3.4.2?

Если ввожу просто:

>_world.


Есть автодополнение.
Если ввожу так:

>for x in _world.


Автодополнения нет, зато выводится ошибка.
Если вручную ввести:

>for x in _world.size:


То при нажатии ctrl+пробел появляется автодополнение.
_world имеет кастомный тип (class_name), если что.

В общем, меня уже давно бесит это назойливое подсказывание ошибок, иногда вместо автодополнения. Если я не дописал выражение до конца - Я ЗНАЮ, ЧТО ЭТО ОШИБКА, зачем мне об этом через пару секунд напоминать? В настройках можно выкрутить частоту парсинга кода до 10 секунд, но нельзя отключить совсем... При этом если поставить на 10 секунд, уже выведенные ошибки тоже будут 10 секунд висеть, до следующего парсинга.

При этом ошибки указывает банальнейшие, самое сложное падает в рантайме или не отлавливается совсем. Сегодня, например, я узнал, что Vector2(0, 0) == false, т.е. не делайте так:

>if vector:


Делайте только так:

>if vector != null:


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

Больше всего бесят рандомные предупреждения типа "здесь присвоение float к int, точность теряется" - с одной стороны, эти предупреждения вообще не отображаются какое-то время, а потом ВНЕЗАПНО их сразу пара десятков, и ты не знаешь, что случилось, почему вдруг только теперь предупреждения. А потом всё равно у тебя логические ошибки в формулах из-за этой потери точности, о которой интерпретатор никак не предупредил.

Впрочем, это всё мелочи, главное что не тормозит на каждом символе при наборе текста, как любят это делать большие IDE...
170 789261
>>89255
А, ещё заметил баг. Если редактор уже отображает какую-то ошибку, поиск по ctrl+f нормально не работает. Т.е. он пишет, сколько всего совпадений, но стрелочки перехода по совпадениям не работают, и не будут работать, пока не исправишь ошибки в коде.

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

>if foo:


>_ bar = 0


>baz = 0


Если bar и baz не существуют, первой ошибкой будет ошибка baz, и только после её исправления будет сообщение про bar. Хотя по логике первым должен быть bar, а только потом - baz. Возможно, это как-то связано с построением дерева кода в анализаторе/интерпретаторе, но мне лично странно видеть именно такой порядок обхода. Delphi и Free Pascal, например, первой ошибкой возвращают ту, что выше по строчкам (bar), и это логично. Хотя Паскаль компилирует код в один проход, что не позволяет объявлять подпрограммы в произвольном порядке (в GDScript произвольный порядок), возможно в этом всё дело, не знаю. В любом случае сообщение о baz и игнорирование bar до исправления baz выглядит нелогичным и неправильным.
171 789284
Аноны, почему окно приложения может быть больше чем заданное в настройках проекта разрешение?
Задал вот 1080\1920, но, как видите, окно гораздо шире.
172 789304
>>89284

>как видите


Ничего не вижу.

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

Т.е. если ты создаёшь окно 1080х1920 на экране 1920х1080, у тебя должен получиться квадрат 1080х1080.

Как обойти? Просто создавай окно 540х960, оно впишется в твой монитор по высоте и будет иметь те же пропорции 9:16 (другое разрешение будет неточным, там десятые доли и т.п.).

Вообще лучше адаптивный дизайн делать, тем более что на мобилках уже давно не 9:16, а от 9:19.5 до 9:21.5 или больше. Производители услышали мемы про лопаты и приняли их за пожелания.
image.png6 Кб, 425x86
173 789308
>>89306 (Del)
А ведь и правда, спасибо, антош.
>>89304
Это не винда, но за пояснение спасибо.

> Вообще лучше адаптивный дизайн делать


Еще бы про это почитать где-то.
Выбрал такое разрешение т.к. оно самое популярное на ведроидах.
174 789331
Давно ничего не постил тут.
Замутил контроллер для платформера на основе конечного автомата. Персонаж умеет прыгать, делает даблджамп, скользит по стенам и делает воллджампы.

Планирую реализовать еще несколько фич:
1) Срезание углов потолка при прыжке вверх (Пик 2)
2) Время койота
3) Инпут буффер. (Игрок может нажать кнопку прыжка за пару кадров до приземления и как только персонаж приземлится он сразу совершит прыжок)
175 789343
>>89331
Ты молодец. Следующий шаг - реализация AI для врагов.
176 789349
>>89343
Врагов еще рано вводить. Хочу механики платформинга отточить и вылизать.
177 789353
Хочу из попавших в AoE врагов выбирать на каждый тик одного рандомного и жахать лично его. (В качестве демонстрации того, что я так себе геймдизайнер, видимо...)
Но не уверен, как это разумно сделать. Можно, конечно, записать get_overlapping_areas.size(), сгенерить рандомный интеджер до этого числа, а потом ещё раз вызвать get_overlapping_areas от этого номера, но так я дважды проверяю коллизии, что, очевидно, тупое решение. Держать что ли в скрипте массив под эти самые overlapping areas? AoEшка в кадре будет одна.
178 789354
>>89353
Да, второе. Надо тупые вопросы задавать самому себе в нотпаде.
179 789359
>>89354

>тупые вопросы


Вопрос не тупой.

>>89353

>get_overlapping_areas


>я дважды проверяю коллизии


Нет.

>For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.


Этот метод возвращает ссылку на массив, который обновляется один раз за физический тик независимо от твоих действий. Т.е. можешь теребить эту функцию сколько хочешь, ни на что это не влияет.

>Держать что ли в скрипте массив под эти самые overlapping areas? AoEшка в кадре будет одна.


А смысл держать "в скрипте"? Куда проще локально:

>var areas := aoe_area.get_overlapping_areas()


>areas[randi() % areas.size()]


Но т.к. массив не обновляется при обращении к этой функции, такая конструкция имеет смысл разве что для более краткой записи.
180 789373
>>89359
Ну с одной стороны респект и уважуха Хуану, что подумал за меня, но с другой стороны писать вопрос с ответом внутри — такое себе развлечение. Второй способ логичнее и во всём лучше, кроме потраченной на кучку указателей памяти.
Кстати, первый метод ещё плох тем, что из него не вычистить какие-нибудь лишние зоны, которые не являются хитбоксами врагов.
Хотя с другой стороны, они на другом слое все лежат, так что это лишняя проверка, надо завести файл с указанием, где у меня такой лишний код, чтобы в случае тормозов разбить стекло.
181 789492
>>89373

>лишние зоны, которые не являются хитбоксами врагов


Просто перемести их на другой слой/измени маску area.

А то, что нельзя переместить на другой слой, фильтруется так:
for area in aoe_area.get_overlapping_areas():
_ if area is Enemy:
_ _ (area as Enemy).deal_damage(aoe_damage.value)

>писать вопрос с ответом внутри — такое себе


Правильно заданный вопрос - половина ответа.
182 789499
Вчера вечером выделил в отдельный скрипт относительно универсальный клеточный автомат. Он ускорил начальные этапы генерации карты и сделал главный скрипт генерации короче и проще благодаря передаче функций с реализацией правил КА:

>_cellular_automaton.run(funcref(self, "_ca_grow_land"), 4)


- в этом примере функция _ca_grow_land() применяется к каждой клетке массива карты, всего 4 прохода по массиву. В результате нужно только создать функции, реализующие правила, и подогнать параметры этих правил под желаемый результат. Кодом я доволен, хотя КА можно дополнительно оптимизировать внутри (решил отложить на потом, т.к. и сейчас нормально), но...

...но меня расстроил конечный результат генерации. Не знаю, чего я ожидал, но рандомный массив точек (как в примерах из интернета) выращивает рандомные же кляксы, некрасивые и слабо напоминающие острова. А дороги через чистый КА вообще не разместить нормально, я смог только ровную сетку сделать (остаток от деления координат клетки на интервал между дорогами). При этом мой изначальный вариант генератора намного чаще выдавал что-то похожее на острова, несмотря на максимально наивный метод (закрашивание рандомных окружностей). А ещё чистый КА сложнее контролировать, т.е. я не знаю заранее, где получится большой остров, а где хрень из мелких кусочков (теоретически знаю: скопление точек = остров, на практике не контролирую).

Я понимаю, что я мог бы реализовать сложные правила, например, симулировать вулканическую и тектоническую активность, приливы с отливами и т.д. Но это в разы усложнит генерацию и не факт что даст хороший контролируемый результат. Остаётся только вернуться к варианту с кругами и сделать процесс генерации более осмысленным, в частности накидывать круги не полностью рандомно, а по набору шаблонов... Судя по Википедии, ИРЛ острова естественного происхождения бывают всего трёх форм:
- большая каменная сиська-вулкан посреди круга;
- длинная гряда сисек, вытянутая вдоль разлома коры;
- дырка от кораллового бублика (сиська утонула).
Т.е. вариант с кругами наиболее близок к ИРЛ островам...

Вместе с тем хочется уже закончить с ландшафтом и перейти к домикам, жителям и машинкам, но я не могу просто пропустить ландшафт, поскольку от него (его данных) зависит всё остальное, за исключением локальных декораций (модельки/текстурки).

1 - что генерировал летом
2 - незначительно обновил этой зимой
3 - прототип на "чистом клеточном автомате"
4 - моё лицо после завершения этого прототипа

Что скажете?
182 789499
Вчера вечером выделил в отдельный скрипт относительно универсальный клеточный автомат. Он ускорил начальные этапы генерации карты и сделал главный скрипт генерации короче и проще благодаря передаче функций с реализацией правил КА:

>_cellular_automaton.run(funcref(self, "_ca_grow_land"), 4)


- в этом примере функция _ca_grow_land() применяется к каждой клетке массива карты, всего 4 прохода по массиву. В результате нужно только создать функции, реализующие правила, и подогнать параметры этих правил под желаемый результат. Кодом я доволен, хотя КА можно дополнительно оптимизировать внутри (решил отложить на потом, т.к. и сейчас нормально), но...

...но меня расстроил конечный результат генерации. Не знаю, чего я ожидал, но рандомный массив точек (как в примерах из интернета) выращивает рандомные же кляксы, некрасивые и слабо напоминающие острова. А дороги через чистый КА вообще не разместить нормально, я смог только ровную сетку сделать (остаток от деления координат клетки на интервал между дорогами). При этом мой изначальный вариант генератора намного чаще выдавал что-то похожее на острова, несмотря на максимально наивный метод (закрашивание рандомных окружностей). А ещё чистый КА сложнее контролировать, т.е. я не знаю заранее, где получится большой остров, а где хрень из мелких кусочков (теоретически знаю: скопление точек = остров, на практике не контролирую).

Я понимаю, что я мог бы реализовать сложные правила, например, симулировать вулканическую и тектоническую активность, приливы с отливами и т.д. Но это в разы усложнит генерацию и не факт что даст хороший контролируемый результат. Остаётся только вернуться к варианту с кругами и сделать процесс генерации более осмысленным, в частности накидывать круги не полностью рандомно, а по набору шаблонов... Судя по Википедии, ИРЛ острова естественного происхождения бывают всего трёх форм:
- большая каменная сиська-вулкан посреди круга;
- длинная гряда сисек, вытянутая вдоль разлома коры;
- дырка от кораллового бублика (сиська утонула).
Т.е. вариант с кругами наиболее близок к ИРЛ островам...

Вместе с тем хочется уже закончить с ландшафтом и перейти к домикам, жителям и машинкам, но я не могу просто пропустить ландшафт, поскольку от него (его данных) зависит всё остальное, за исключением локальных декораций (модельки/текстурки).

1 - что генерировал летом
2 - незначительно обновил этой зимой
3 - прототип на "чистом клеточном автомате"
4 - моё лицо после завершения этого прототипа

Что скажете?
183 789512
>>89499

> Что скажете?


Мне норм. Включая игру, я не собираюсь изучать по ней геологию. Есть островки, есть дороги и домики. И мне похуй, вулканический остров это или тектонический, из осадочных пород там берега образовались или намыло приливами. Геймплей завези, плиз.
184 789532
>>89512

>вулканический остров это или тектонический, из осадочных пород там берега образовались или намыло приливами


Это понятно что без разницы. Разница в том, что будет выглядеть привлекательнее, а ИРЛ острова привлекательны по определению (мы так или иначе видим их с детства по телевизору, в книгах, играх и так далее, т.е. привыкли и ожидаем увидеть именно такими). Хочешь привлекательный остров процедурно - симулируй реальные процессы происхождения островов, логично? Логично. Если просто рассыпать случайную кучку пикселей, она не будет похожа на остров, и никакие виртуальные пальмы (фантик, декорация) не сделают эту кучку пикселей привлекательнее.

С другой стороны, мне нужна не столько симуляция, сколько контроль за появлением тех или иных особенностей, чтобы не нужно было детектить их наличие по состоянию клеток. К примеру, на скриншотах выше видно мелкие озёра - но ни в одном из случаев моя программа не знает о наличии этих озёр, следовательно не сможет поместить туда, например, курортные домики. Если бы я симулировал формирование озёр, программа бы знала, где они находятся, хотя бы примерно, но я так и не нашёл удобного способа симуляции кроме вырезания окружностей (или прямоугольников, но они совсем унылые формы дают). Т.е. не так важна реалистичность, сколько контроль за тем, что именно образуется на карте. Чистый КА такого контроля, к сожалению, не даёт (им только постобработку делать можно, типа песка между водой и землёй), поэтому придётся делать что-то комбинированное.

>Геймплей завези, плиз.


Так у меня геймплей мечты сильно зависит от работы генератора. Самый базовый геймплей - это перемещение по миру и наблюдение за этим миром. Всё остальное вторично, не обязывает игрока что-то делать, не тычет в лицо указателями "топай сюда", не ставит целей, не заставляет выполнять задачи, собирать коллекции и прочее. Просто вот тебе мир, уже готовый и функционирующий сам по себе, делай в нём что захочется в рамках предоставленных возможностей. Идеал песочницы. Так вот фан этого базового геймплея сильно зависит от того, что способен выдать генератор мира. Если мир фундаментально некрасив и неинтересен, то и этот геймплей будет в нём скучным. Я это не с потолка беру, у меня уже много прототипов было, как процедурных, так и сделанных полностью вручную - всякий раз уделяю время на просто побегать/покататься, чтобы оценить ощущения от этой голой базы мира. В общем, не будет толкового генератора, не будет и геймплея, т.к. вручную собирать уровни мне совсем не хочется, от рукотворных карт совсем другие ожидания (честно пробовал несколько раз - мне не понравилось, даже примитивный генератор лучше ковыряния в редакторе карт, по крайней мере с позиции соло программиста-любителя).

Хотя в той же степени этот геймплей зависит от графики, в частности генераторов зданий/машин/жителей/леса и т.д., т.е. не ландшафтом единым, нужно будет ещё куча всего. Но повторюсь, эта куча всего опирается на ландшафт как на фундамент, и если ландшафт - унылая клякса, то и остальное тоже будет как нарост на унылой кляксе. Из этого следует, что ландшафт должен быть интересным и привлекательным без всего остального, т.е. до этапа установки домиков и прочей декорации. Поэтому и вожусь с этим всем столько времени, пробую варианты, пока не окажусь доволен результатом без всяких "но" (к примеру, то, что сейчас есть, выдаёт хороший результат не каждый раз, примерно больше половины - скучная или вообще неиграбельная хрень, иногда вообще один малюсенький клочок земли без всего, это никуда не годится - нужно переделывать).

Многобуков и "а мог бы в это время код писать/игру делать", но на самом деле упорядочить мысли и цели по игре намного важнее, чем писать код или лепить контент, так-то. А то иногда сажусь за комп, открываю проект, смотрю на то, что сделано, и понятия не имею, что я вообще должен/хотел сделать. Строгое планирование/диздок вообще не помогают, только нервируют и запутывают...
184 789532
>>89512

>вулканический остров это или тектонический, из осадочных пород там берега образовались или намыло приливами


Это понятно что без разницы. Разница в том, что будет выглядеть привлекательнее, а ИРЛ острова привлекательны по определению (мы так или иначе видим их с детства по телевизору, в книгах, играх и так далее, т.е. привыкли и ожидаем увидеть именно такими). Хочешь привлекательный остров процедурно - симулируй реальные процессы происхождения островов, логично? Логично. Если просто рассыпать случайную кучку пикселей, она не будет похожа на остров, и никакие виртуальные пальмы (фантик, декорация) не сделают эту кучку пикселей привлекательнее.

С другой стороны, мне нужна не столько симуляция, сколько контроль за появлением тех или иных особенностей, чтобы не нужно было детектить их наличие по состоянию клеток. К примеру, на скриншотах выше видно мелкие озёра - но ни в одном из случаев моя программа не знает о наличии этих озёр, следовательно не сможет поместить туда, например, курортные домики. Если бы я симулировал формирование озёр, программа бы знала, где они находятся, хотя бы примерно, но я так и не нашёл удобного способа симуляции кроме вырезания окружностей (или прямоугольников, но они совсем унылые формы дают). Т.е. не так важна реалистичность, сколько контроль за тем, что именно образуется на карте. Чистый КА такого контроля, к сожалению, не даёт (им только постобработку делать можно, типа песка между водой и землёй), поэтому придётся делать что-то комбинированное.

>Геймплей завези, плиз.


Так у меня геймплей мечты сильно зависит от работы генератора. Самый базовый геймплей - это перемещение по миру и наблюдение за этим миром. Всё остальное вторично, не обязывает игрока что-то делать, не тычет в лицо указателями "топай сюда", не ставит целей, не заставляет выполнять задачи, собирать коллекции и прочее. Просто вот тебе мир, уже готовый и функционирующий сам по себе, делай в нём что захочется в рамках предоставленных возможностей. Идеал песочницы. Так вот фан этого базового геймплея сильно зависит от того, что способен выдать генератор мира. Если мир фундаментально некрасив и неинтересен, то и этот геймплей будет в нём скучным. Я это не с потолка беру, у меня уже много прототипов было, как процедурных, так и сделанных полностью вручную - всякий раз уделяю время на просто побегать/покататься, чтобы оценить ощущения от этой голой базы мира. В общем, не будет толкового генератора, не будет и геймплея, т.к. вручную собирать уровни мне совсем не хочется, от рукотворных карт совсем другие ожидания (честно пробовал несколько раз - мне не понравилось, даже примитивный генератор лучше ковыряния в редакторе карт, по крайней мере с позиции соло программиста-любителя).

Хотя в той же степени этот геймплей зависит от графики, в частности генераторов зданий/машин/жителей/леса и т.д., т.е. не ландшафтом единым, нужно будет ещё куча всего. Но повторюсь, эта куча всего опирается на ландшафт как на фундамент, и если ландшафт - унылая клякса, то и остальное тоже будет как нарост на унылой кляксе. Из этого следует, что ландшафт должен быть интересным и привлекательным без всего остального, т.е. до этапа установки домиков и прочей декорации. Поэтому и вожусь с этим всем столько времени, пробую варианты, пока не окажусь доволен результатом без всяких "но" (к примеру, то, что сейчас есть, выдаёт хороший результат не каждый раз, примерно больше половины - скучная или вообще неиграбельная хрень, иногда вообще один малюсенький клочок земли без всего, это никуда не годится - нужно переделывать).

Многобуков и "а мог бы в это время код писать/игру делать", но на самом деле упорядочить мысли и цели по игре намного важнее, чем писать код или лепить контент, так-то. А то иногда сажусь за комп, открываю проект, смотрю на то, что сделано, и понятия не имею, что я вообще должен/хотел сделать. Строгое планирование/диздок вообще не помогают, только нервируют и запутывают...
185 789534
>>89532
Ты с таким подходом рискуешь выгореть быстрее чем что-либо сделаешь
186 789563
>>89532

> Хочешь привлекательный остров процедурно - симулируй реальные процессы происхождения островов, логично? Логично.


Нет.
Привлекательность не так работает. Есть набор шаблонов, которые ты можешь субъективно разделить на привлекательные и нет. Вот и всё. Никакая симуляция никаких процессов тупо не нужна. Нужно тупо привлекательные шаблоны тасовать в колоде и выкладывать зрителям по одному.

> контроль за появлением тех или иных особенностей


Удваиваю предыдущего анона. Ты перфекционист, улетевший в перфекционистские дали (титанически удерживаю себя от написания обидного слова на букву манямирок). Никакой игры здесь не будет. Игровая индустрия это не про то, как симулировать процессы, а про то, как подавать игроку на рецепторы красивые шаблоны, объединённые правилами, следуя которым игрок выигрывает. Всё, блять. Симуляция реальности не нужна. Либо шашечки, либо ехать.

> Самый базовый геймплей - это перемещение по миру и наблюдение за этим миром. Всё остальное вторично, не обязывает игрока что-то делать


Ой всё. Жирнота потекла. Пойду допишу остальные буквы к слову на букву м.
едрён батон.png100 Кб, 279x321
187 789604
>>89499

>относительно универсальный клеточный автомат


Переделал в полностью универсальный двумерный КА, отвязав его от хранилища мира с помощью FuncRef - теперь ему нужны только ссылки на геттер и сеттер для получения и возврата данных. Сделал скриншот кода и собирался скинуть сюда, но отвлёкся, а потом комп заглючил. Если кому интересно, завтра попытаюсь скинуть, там 67 строк с пробелами и комментариями.

>>89583 (Del)

>Все правильно делаешь,


Спасибо.

>главное чтобы самому нравилось.


Тоже так считаю.

>>89534

>рискуешь выгореть


Уже года 3 выгораю с этого проекта, а первые идеи сделать такую игру появились лет 13 назад (многое поменялось, но суть та же). Ничего, после перерыва возвращаюсь, т.к. больше заняться нечем: другие идеи игр меня не привлекают в достаточной степени (много их было), а другие мечты слишком сложны.

>>89563

>Нужно тупо привлекательные шаблоны тасовать в колоде и выкладывать зрителям по одному.


Это я понимаю. Проблема в том, что вручную много шаблонов не сделаешь. Это частая проблема генераторов: шаблонов мало, увидел каждый шаблон по одному разу - считай, увидел все возможные результаты генерации. Я хотел избежать этого, предоставив алгоритмам больше свободы, но такая свобода лишает контроля за происходящим. Подробную реалистичную симуляцию я, конечно, делать не буду, просто рассматривал как одну из альтернатив.

>Ты перфекционист


Да, это так. Но ты, по-моему, не понял, о каком контроле речь. Простой пример: морской порт лучше расположить там, где участки суши окружают воду, но как я пойму, что вот этот блок песка находится в подходящем месте? Если выбирать рандомный блок песка, порт может оказаться в озере или локальной пустыне. Можно придумать разные способы определения места, но все они будут сложными. Значит, нужно делать наоборот: создать подходящий для порта участок на острове, запомнить его положение и потом поставить туда порт. Так шанс случайно сделать порт в луже или в пустыне значительно снижается. Моя изначальная и самая главная проблема в том, что я не знаю, как описать все эти "специальные места" так, чтобы результат не выглядел как набор повторяющихся из раза в раз банальных прямоугольников.

Пока писал это, подумалось, что, наверное, самым простым будет решение с подстановкой заранее заготовленных участков карты разных размеров. Не в виде 3D мешей, а в виде наборов типов блоков или даже метаблоков. Можно даже сделать разные уровни детализации, с превращением высокоуровневых метаблоков в низкоуровневые блоки и субблоки. По-моему, как-то похоже реализованы деревни в Майнкрафте и карты в Cataclysm:DDA. Останется только заготовить побольше шаблонов... Но тогда вся магия генерации исчезнет и останется только тупой рандом на наборе шаблонов, печаль-беда. Хотя так можно будет вывести шаблоны наружу через JSON, чтобы свободно дополнять их... Кажется, головоломка начинает складываться.

>Игровая индустрия


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

>игрок выигрывает


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

>Симуляция реальности не нужна.


Ты отрицаешь существование целого жанра игр? Симуляторы порой могут доходить до уровня проработанности, когда их и играми-то не назовёшь, но в них тоже играют. Мне лично было тяжело разобраться методом тыка с реалистичным взлётом самолёта в авиасимуляторах и я не уверен, что разобрался до конца, но к моему удивлению, люди любят заниматься такими сложностями, любят в это играть. Та же ситуация с механической коробкой передач в автосимуляторах, никогда не понимал фана от слежения за числом оборотов, но в автомобиле ты хотя бы не взрываешься, нажав не ту кнопку. Просто эти жанры не для меня и не для тебя, но они существуют и нельзя отрицать потребность в их существовании.

>Жирнота потекла


Это твой пост - жирнота, ты не можешь не знать целых жанров игр, пускай и нишевых. Не прикидывайся, ты видел многие игры, в которых минимум геймплея и графики, а сюжета и вовсе нет как такового, но аудитория и даже фанаты имеются.
едрён батон.png100 Кб, 279x321
187 789604
>>89499

>относительно универсальный клеточный автомат


Переделал в полностью универсальный двумерный КА, отвязав его от хранилища мира с помощью FuncRef - теперь ему нужны только ссылки на геттер и сеттер для получения и возврата данных. Сделал скриншот кода и собирался скинуть сюда, но отвлёкся, а потом комп заглючил. Если кому интересно, завтра попытаюсь скинуть, там 67 строк с пробелами и комментариями.

>>89583 (Del)

>Все правильно делаешь,


Спасибо.

>главное чтобы самому нравилось.


Тоже так считаю.

>>89534

>рискуешь выгореть


Уже года 3 выгораю с этого проекта, а первые идеи сделать такую игру появились лет 13 назад (многое поменялось, но суть та же). Ничего, после перерыва возвращаюсь, т.к. больше заняться нечем: другие идеи игр меня не привлекают в достаточной степени (много их было), а другие мечты слишком сложны.

>>89563

>Нужно тупо привлекательные шаблоны тасовать в колоде и выкладывать зрителям по одному.


Это я понимаю. Проблема в том, что вручную много шаблонов не сделаешь. Это частая проблема генераторов: шаблонов мало, увидел каждый шаблон по одному разу - считай, увидел все возможные результаты генерации. Я хотел избежать этого, предоставив алгоритмам больше свободы, но такая свобода лишает контроля за происходящим. Подробную реалистичную симуляцию я, конечно, делать не буду, просто рассматривал как одну из альтернатив.

>Ты перфекционист


Да, это так. Но ты, по-моему, не понял, о каком контроле речь. Простой пример: морской порт лучше расположить там, где участки суши окружают воду, но как я пойму, что вот этот блок песка находится в подходящем месте? Если выбирать рандомный блок песка, порт может оказаться в озере или локальной пустыне. Можно придумать разные способы определения места, но все они будут сложными. Значит, нужно делать наоборот: создать подходящий для порта участок на острове, запомнить его положение и потом поставить туда порт. Так шанс случайно сделать порт в луже или в пустыне значительно снижается. Моя изначальная и самая главная проблема в том, что я не знаю, как описать все эти "специальные места" так, чтобы результат не выглядел как набор повторяющихся из раза в раз банальных прямоугольников.

Пока писал это, подумалось, что, наверное, самым простым будет решение с подстановкой заранее заготовленных участков карты разных размеров. Не в виде 3D мешей, а в виде наборов типов блоков или даже метаблоков. Можно даже сделать разные уровни детализации, с превращением высокоуровневых метаблоков в низкоуровневые блоки и субблоки. По-моему, как-то похоже реализованы деревни в Майнкрафте и карты в Cataclysm:DDA. Останется только заготовить побольше шаблонов... Но тогда вся магия генерации исчезнет и останется только тупой рандом на наборе шаблонов, печаль-беда. Хотя так можно будет вывести шаблоны наружу через JSON, чтобы свободно дополнять их... Кажется, головоломка начинает складываться.

>Игровая индустрия


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

>игрок выигрывает


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

>Симуляция реальности не нужна.


Ты отрицаешь существование целого жанра игр? Симуляторы порой могут доходить до уровня проработанности, когда их и играми-то не назовёшь, но в них тоже играют. Мне лично было тяжело разобраться методом тыка с реалистичным взлётом самолёта в авиасимуляторах и я не уверен, что разобрался до конца, но к моему удивлению, люди любят заниматься такими сложностями, любят в это играть. Та же ситуация с механической коробкой передач в автосимуляторах, никогда не понимал фана от слежения за числом оборотов, но в автомобиле ты хотя бы не взрываешься, нажав не ту кнопку. Просто эти жанры не для меня и не для тебя, но они существуют и нельзя отрицать потребность в их существовании.

>Жирнота потекла


Это твой пост - жирнота, ты не можешь не знать целых жанров игр, пускай и нишевых. Не прикидывайся, ты видел многие игры, в которых минимум геймплея и графики, а сюжета и вовсе нет как такового, но аудитория и даже фанаты имеются.
1644138819172.png96 Кб, 730x588
188 789635
>>89604

> как я пойму, что вот этот блок песка находится в подходящем месте?


Например твой генератор будет выдавать нужные тебе метаданные вместе с картинкой.

> как описать все эти "специальные места"


Вот как делаю я.
1. Сначала проходишься по массиву данных первым проходом. И считаешь нужные тебе условия.
2. Эти условия нарастающим инкрементом выводишь в специльные переменные.
3. При необходимости можешь сделать второй проход с учётом полученных на первом проходе данных.
4. В конце при помощи сравнений и иных вычислений, делаешь нужные тебе выводы.
В твоём случае, с дивана мне видятся следующие условия, которые можно посчитать, проходя по пикселям сгенерированного острова и вычисляя по цвету пикселя биом, вычислить, лужа это, пустыня, береговая линия, и т.п.

В качестве примера пикрелейтед с комментами как этот принцип применял я.
189 789766
>>89331
Добавил время койота и буффер прыжка. Теперь персонаж может прыгнуть если игрок нажал кнопку чуть раньше нужного или чуть позже.
Так же поменял коллизию персонажа на вот такой полигон. Из-за этого стало очень удобно запрыгивать в узкие дырки размером с персонажа и прыгать из-под крыши.
190 789767
>>89766
Помимо этого добавил пару фич по физике. Максимальная скорость падения и уменьшение гравитации, когда скорость падения близка к нулю. Это видно по трейлу - он немного "приплюснут" сверху. Таким образом игрок получает больше контроля над персонажем.
191 789772
>>89635
Мимо с нулевой. У вас в гдскрипте хоть кто-то пишет нормальный код, а не вот этот набор ифов и свичтей? Паттерны, инкапсуляция, вот это вот все.
192 789782
Так, пацаны, чзх? Щас беру копипасту из своего старого кода, а она не работает. В какой момент изменилась функция Vector2.angle_to_point(to) ?
Я чётко помню, что в 3.2 было так:

>Vector2.ZERO.angle_to_point(Vector2.RIGHT) -> 0


>Vector2.ZERO.angle_to_point(Vector2(-1, 0.0001)) -> 3.14


>Vector2.ZERO.angle_to_point(Vector2(-1, -0.0001)) -> -3.14


Теперь почему-то наоборот:

>Vector2.ZERO.angle_to_point(Vector2.LEFT) -> 0


>Vector2.ZERO.angle_to_point(Vector2(1, 0.0001)) -> -3.14


>Vector2.ZERO.angle_to_point(Vector2(1, -0.0001)) -> 3.14



Это какой-то пиздец.

>print (Vector2.UP.angle())


>print (Vector2.ZERO.angle_to_point(Vector2.UP))


> > -1.570796


> > 1.570796


>print (Vector2(1,1).angle())


>print (Vector2.ZERO.angle_to_point(Vector2(1,1)))


> > 0.785398


> > -2.356194


Ну и как это понимать? Какого хуя теперь результаты отличаются?
193 789785
>>89783 (Del)
Не сразу понял, что за короткий адрес.
Крч в четвёрке исправят, а пока так оставят, няп.
194 789835
>>89772

> нормальный код, а не вот этот набор ифов и свичтей?


Покажи пример.
195 789957
>>89604

>полностью универсальный двумерный КА


>завтра попытаюсь скинуть


Годосподин скозал - годосподин сделол.

>самым простым будет решение с подстановкой заранее заготовленных участков карты разных размеров


>вывести шаблоны наружу через JSON


Тщательно всё обдумол - такой способ никуда не годится. Вручную циферками (или даже именами) описывать участки визуальной карты - боль, а редактор я делать не хочу. К тому же один универсальный размер не подходит для всех видов структур сразу - нельзя просто взять и разделить карту на 4/9/16/N квадратов рекурсивно. А чтобы мир был нескучным, потребуется огромное число шаблонов. Конечно, можно поступить проще и реализовать это (давно об этом способе знал, но не интересовался и забыл):
https://ijdykeman.github.io/ml/2017/10/12/wang-tile-procedural-generation.html
Но, судя по всему, этот вид генерации практически неуправляемый, результаты его непредсказуемы и потому мне совсем не подходят. Мне нужно что-то более "дизайнерское", но при этом не слишком шаблонное (рандома, рандома побольше насыпьте!). Сам понимаю, что мои желания противоречивы... К примеру, я хочу чёткий набор параметров мира, которыми можно будет управлять перед началом новой игры, что-то типа настроек мира Don't Starve, вплоть до указания точного числа объектов (пример: не просто "озёра: средне", а опциональное "озёра: 3 шт.", и пусть генератор сам решит, как и куда их можно пристроить, но условие должно быть выполнено).

Так что теперь я возвращаюсь к идее, которую обдумывал уже очень давно и всё не решался начать: ой-вей ОО-вей. План таков: инкапсулирую все объективно объективные объекты мира в классы, создаю горсть объектов нужных типов, высыпаю их все в общий контейнер, закрываю крышечку, трясу контейнер, получаю на выходе нормальную тайловую карту мира, на которой точно известны все достопримечательности, которые могут понадобиться в процессе или после генерации. Набросал немного тестовых классов и что-то мне поплохело, наверное, нужно в один файл собрать...

>>89635

>>как я пойму, что...


>твой генератор будет выдавать нужные тебе метаданные


WTF? Как мой генератор сделает нужные мне метаданные?
Ты же по сути вопроса не ответил.
— Как мне пройти к...
— Ножками, ножками, топ-топ-топ и прошёл!
— Как мне найти...
— Встал, поискал и нашёл! Поискал и нашёл!
— Как мне сделать...
— Ручками, всё ручками, оп-оп-оп и готово!

>проходишься по массиву данных


>при помощи сравнений и иных вычислений


Так я и пытаюсь избавиться от необходимости проходить по финальному массиву (матрице) и вычислять наличие каких-то особенностей. Причин на то сразу несколько:
- это ресурсоёмко, возможно, даже больше генерации;
- долго и сложно отлаживать ошибки распознавания;
- это не позволяет контролировать содержимое карты, т.е. в случае неудачной генерации остаётся только начинать с нуля.
Да, конечно, можно формально описать свойства необходимых миров, а потом тупо брутфорсить все возможные комбинации ячеек карты, надеясь найти хорошие комбинации, но я не математическую задачку на суперкомпьютере решаю, чтобы брутфорсить огромные числа. Так что нужно сначала составлять список всех необходимых особенностей мира и определять их параметры (положение, размер и всё остальное), а потом проецировать их хоть на квадратную, хоть на гексагональную сетку (были мысли о ней, есть прототип, но сглаживать её очень трудно, а на машинках по ступенькам особо не поездишь, да и привычные перекрёстки невозможны без костылей). Это также причина отказа от всяких функций шума и многих других вариантов генерации - они хоть и дают неплохой визуально результат, но управлять им практически невозможно, предел всех этих нойзов - наложить текстурки и воткнуть деревья в зависимости от высоты над уровнем моря, что очень ограничивает полёт фантазии. Хочешь что-то более продвинутое - изобретай специализированный велосипед...

>>89772

>нормальный код


На пикриле нормальный код? Обычно я стараюсь придерживаться ООП, но процедурный код пишется быстрее, позволяет быстрее получить рабочий прототип. Зачот языкам, которые позволяют безболезненно смешивать объектный и процедурный подход в рамках одного файла. Ну, в случае GDScript разница между ООП и процедурным подходом практически не ощущается, т.к. нет специфичного для ООП синтаксического сахара - просто пишешь кучу подпрограмм, не задумываясь о том, являются ли они отдельными сущностями или частями некоего объекта. Думаю, это специально сделано для снижения порога входа новичков, ООП есть, но тебя никто не тычет в него носом. С другой стороны, конечно, это слишком расслабляет и ты можешь наломать дров, например, сделать огромный божественный объект.
195 789957
>>89604

>полностью универсальный двумерный КА


>завтра попытаюсь скинуть


Годосподин скозал - годосподин сделол.

>самым простым будет решение с подстановкой заранее заготовленных участков карты разных размеров


>вывести шаблоны наружу через JSON


Тщательно всё обдумол - такой способ никуда не годится. Вручную циферками (или даже именами) описывать участки визуальной карты - боль, а редактор я делать не хочу. К тому же один универсальный размер не подходит для всех видов структур сразу - нельзя просто взять и разделить карту на 4/9/16/N квадратов рекурсивно. А чтобы мир был нескучным, потребуется огромное число шаблонов. Конечно, можно поступить проще и реализовать это (давно об этом способе знал, но не интересовался и забыл):
https://ijdykeman.github.io/ml/2017/10/12/wang-tile-procedural-generation.html
Но, судя по всему, этот вид генерации практически неуправляемый, результаты его непредсказуемы и потому мне совсем не подходят. Мне нужно что-то более "дизайнерское", но при этом не слишком шаблонное (рандома, рандома побольше насыпьте!). Сам понимаю, что мои желания противоречивы... К примеру, я хочу чёткий набор параметров мира, которыми можно будет управлять перед началом новой игры, что-то типа настроек мира Don't Starve, вплоть до указания точного числа объектов (пример: не просто "озёра: средне", а опциональное "озёра: 3 шт.", и пусть генератор сам решит, как и куда их можно пристроить, но условие должно быть выполнено).

Так что теперь я возвращаюсь к идее, которую обдумывал уже очень давно и всё не решался начать: ой-вей ОО-вей. План таков: инкапсулирую все объективно объективные объекты мира в классы, создаю горсть объектов нужных типов, высыпаю их все в общий контейнер, закрываю крышечку, трясу контейнер, получаю на выходе нормальную тайловую карту мира, на которой точно известны все достопримечательности, которые могут понадобиться в процессе или после генерации. Набросал немного тестовых классов и что-то мне поплохело, наверное, нужно в один файл собрать...

>>89635

>>как я пойму, что...


>твой генератор будет выдавать нужные тебе метаданные


WTF? Как мой генератор сделает нужные мне метаданные?
Ты же по сути вопроса не ответил.
— Как мне пройти к...
— Ножками, ножками, топ-топ-топ и прошёл!
— Как мне найти...
— Встал, поискал и нашёл! Поискал и нашёл!
— Как мне сделать...
— Ручками, всё ручками, оп-оп-оп и готово!

>проходишься по массиву данных


>при помощи сравнений и иных вычислений


Так я и пытаюсь избавиться от необходимости проходить по финальному массиву (матрице) и вычислять наличие каких-то особенностей. Причин на то сразу несколько:
- это ресурсоёмко, возможно, даже больше генерации;
- долго и сложно отлаживать ошибки распознавания;
- это не позволяет контролировать содержимое карты, т.е. в случае неудачной генерации остаётся только начинать с нуля.
Да, конечно, можно формально описать свойства необходимых миров, а потом тупо брутфорсить все возможные комбинации ячеек карты, надеясь найти хорошие комбинации, но я не математическую задачку на суперкомпьютере решаю, чтобы брутфорсить огромные числа. Так что нужно сначала составлять список всех необходимых особенностей мира и определять их параметры (положение, размер и всё остальное), а потом проецировать их хоть на квадратную, хоть на гексагональную сетку (были мысли о ней, есть прототип, но сглаживать её очень трудно, а на машинках по ступенькам особо не поездишь, да и привычные перекрёстки невозможны без костылей). Это также причина отказа от всяких функций шума и многих других вариантов генерации - они хоть и дают неплохой визуально результат, но управлять им практически невозможно, предел всех этих нойзов - наложить текстурки и воткнуть деревья в зависимости от высоты над уровнем моря, что очень ограничивает полёт фантазии. Хочешь что-то более продвинутое - изобретай специализированный велосипед...

>>89772

>нормальный код


На пикриле нормальный код? Обычно я стараюсь придерживаться ООП, но процедурный код пишется быстрее, позволяет быстрее получить рабочий прототип. Зачот языкам, которые позволяют безболезненно смешивать объектный и процедурный подход в рамках одного файла. Ну, в случае GDScript разница между ООП и процедурным подходом практически не ощущается, т.к. нет специфичного для ООП синтаксического сахара - просто пишешь кучу подпрограмм, не задумываясь о том, являются ли они отдельными сущностями или частями некоего объекта. Думаю, это специально сделано для снижения порога входа новичков, ООП есть, но тебя никто не тычет в него носом. С другой стороны, конечно, это слишком расслабляет и ты можешь наломать дров, например, сделать огромный божественный объект.
1644260398707.png186 Кб, 1160x684
196 789971
>>89957

> Как мой генератор сделает нужные мне метаданные?


Мда, я щас пожалуй и правда толстоту напишу, но я не могу молчать. Выкинь этот генератор и напиши другой, который сможет метаданные выдавать. Как в программе World Machine, у которой ноды кроме входных данных имеют несколько выходных пинов.
197 789978
>>89971

>Выкинь этот генератор и напиши другой, который сможет метаданные выдавать.


Капитан очевидность, ты? Ты думаешь, чем я последние два-три года занимаюсь? Переписываю генераторы с нуля. Уже со счёту сбился и не помню всех. А ты, похоже, не разбираешься в теме, раз пишешь "метаданные выдавать" - кому выдавать и откуда? Метаданные нужно сначала сгенерировать, а потом самому же (в пределах генератора) использовать для финального этапа, на котором получатся основные данные мира - тайловая карта. Типа "у этого острова два озера, одно на севере, другое на западе, северное маленькое, западное средних размеров" - это мета, она должна идти перед финальной генерацией тайловой карты, поскольку выводить её из готовой тайловой карты - задача, сравнимая по сложности с компьютерным зрением. Моя проблема только в том, что я решил по-быстрому сделать сразу тайловую карту, проскочив этап генерации меты.

>>89635

>как этот принцип применял я


Вчитался в твой код. Мне кажется, ты всё слишком усложнил. Это, конечно, зависит от формата хранения игрового поля и некоторых других частей игры, но я бы сделал так:

>func _is_game_over() -> bool:


>_ if flag_count != mines.size():


>_ _ return false # число флагов не соответствует числу мин


>_ for mine in mines: # список мин отдельно от поля


>_ _ if not mine.flagged:


>_ _ _ return false # минимум одна мина не отмечена флагом


>_ return true # все мины отмечены и нет лишних флагов


Суть в том, что тебе не нужно перебирать всё игровое поле и каждый раз пересчитывать число флагов. Счётчик флагов (flag_count) должен обновляться после каждой установки/снятия флага игроком, потому что флаги - это не отдельные сущности, это просто метки, и ты точно знаешь их количество. А перебирать всё поле не нужно потому, что, во-первых, тебе не важны позиции мин на поле и сами мины не могут никак изменяться. Мины в массиве field нужны только для отображения поля, в остальном лучше иметь к ним доступ из отдельного массива (всё равно это Dictionary, которые передаются по ссылке, следовательно, "вашу мину и там, и тут передают").

Хотя ещё лучше было бы отказаться от Dictionary и иметь массив простых int, например, с такими значениями:
-7 - метка "вопрос" на пустой клетке,
-6 - метка "флаг" на пустой клетке, (const FLAG_EMPTY = -6)
-5 - метка "вопрос" на мине,
-4 - метка "флаг" на мине,
-3 - ошибочная метка "флаг",
-2 - взорванная мина,
-1 - мина без метки, (const MINE = -1)
0 - пустая закрытая клетка без метки, (const EMPTY = 0)
1-8 - число мин вокруг открытой клетки,
9 - открытая клетка без числа.

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

>func _is_game_over() -> bool:


>_ if flag_count != mine_count:


>_ _ return false # число флагов не соответствует числу мин


>_ for cell in field:


>_ _ if cell == FLAG_EMPTY or cell == MINE:


>_ _ _ return false # минимум одна мина не отмечена флагом


>_ return true # все мины отмечены и нет лишних флагов


Здесь mine_count тоже заранее известно, потому что, во-первых, игрок задаёт это число в самом начале игры, во-вторых, ты генерируешь заранее известное тебе число мин. Остальное как и в первом примере, только теперь можно проверить неправильные флаги (флаг на пустой клетке = какой-то мине не хватило флага).

И, конечно, описанная функция не должна изменять состояние игры, она лишь определяет завершение игры. Её нужно использовать где-то в другом месте, скорее всего, после успешного размещения очередного флага (потому что открытие клетки либо однозначно завершает игру взрывом, либо однозначно продолжает её):

>func _on_flag_placed() -> void:


>_ if _is_game_over():


>_ _ emit_signal("game_over")



...а вообще-то, можно сделать ещё проще: совсем избавиться от пробега по каким-либо массивам. Лол, даже не подумал об этом изначально. Короче:

>func _on_flag_placed(cell_id: int) -> void:


>_ match field[cell_id]:


>_ _ EMPTY:


>_ _ _ flag_count += 1


>_ _ _ field[cell_id] = FLAG_EMPTY


>_ _ _ game_state = WRONG_FLAG


># бла-бла-бла, все состояния клеток обрабатываем...


>_ if flag_count == mine_count and game_state != WRONG_FLAG:


>_ _ emit_signal("game_over")


Видишь, нам не нужно обрабатывать всё поле после каждого клика, нам достаточно изменять клетку, по которой кликнули, число установленных флагов и состояние игры - корректно установлены флаги (только на минах) или нет (на пустых клетках). Итого избавились сразу и от Dictionary, и от лишнего прохода по каким-либо массивам, максимально оптимизировав игру.

Как же я хорош, как мощны мои коды...
197 789978
>>89971

>Выкинь этот генератор и напиши другой, который сможет метаданные выдавать.


Капитан очевидность, ты? Ты думаешь, чем я последние два-три года занимаюсь? Переписываю генераторы с нуля. Уже со счёту сбился и не помню всех. А ты, похоже, не разбираешься в теме, раз пишешь "метаданные выдавать" - кому выдавать и откуда? Метаданные нужно сначала сгенерировать, а потом самому же (в пределах генератора) использовать для финального этапа, на котором получатся основные данные мира - тайловая карта. Типа "у этого острова два озера, одно на севере, другое на западе, северное маленькое, западное средних размеров" - это мета, она должна идти перед финальной генерацией тайловой карты, поскольку выводить её из готовой тайловой карты - задача, сравнимая по сложности с компьютерным зрением. Моя проблема только в том, что я решил по-быстрому сделать сразу тайловую карту, проскочив этап генерации меты.

>>89635

>как этот принцип применял я


Вчитался в твой код. Мне кажется, ты всё слишком усложнил. Это, конечно, зависит от формата хранения игрового поля и некоторых других частей игры, но я бы сделал так:

>func _is_game_over() -> bool:


>_ if flag_count != mines.size():


>_ _ return false # число флагов не соответствует числу мин


>_ for mine in mines: # список мин отдельно от поля


>_ _ if not mine.flagged:


>_ _ _ return false # минимум одна мина не отмечена флагом


>_ return true # все мины отмечены и нет лишних флагов


Суть в том, что тебе не нужно перебирать всё игровое поле и каждый раз пересчитывать число флагов. Счётчик флагов (flag_count) должен обновляться после каждой установки/снятия флага игроком, потому что флаги - это не отдельные сущности, это просто метки, и ты точно знаешь их количество. А перебирать всё поле не нужно потому, что, во-первых, тебе не важны позиции мин на поле и сами мины не могут никак изменяться. Мины в массиве field нужны только для отображения поля, в остальном лучше иметь к ним доступ из отдельного массива (всё равно это Dictionary, которые передаются по ссылке, следовательно, "вашу мину и там, и тут передают").

Хотя ещё лучше было бы отказаться от Dictionary и иметь массив простых int, например, с такими значениями:
-7 - метка "вопрос" на пустой клетке,
-6 - метка "флаг" на пустой клетке, (const FLAG_EMPTY = -6)
-5 - метка "вопрос" на мине,
-4 - метка "флаг" на мине,
-3 - ошибочная метка "флаг",
-2 - взорванная мина,
-1 - мина без метки, (const MINE = -1)
0 - пустая закрытая клетка без метки, (const EMPTY = 0)
1-8 - число мин вокруг открытой клетки,
9 - открытая клетка без числа.

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

>func _is_game_over() -> bool:


>_ if flag_count != mine_count:


>_ _ return false # число флагов не соответствует числу мин


>_ for cell in field:


>_ _ if cell == FLAG_EMPTY or cell == MINE:


>_ _ _ return false # минимум одна мина не отмечена флагом


>_ return true # все мины отмечены и нет лишних флагов


Здесь mine_count тоже заранее известно, потому что, во-первых, игрок задаёт это число в самом начале игры, во-вторых, ты генерируешь заранее известное тебе число мин. Остальное как и в первом примере, только теперь можно проверить неправильные флаги (флаг на пустой клетке = какой-то мине не хватило флага).

И, конечно, описанная функция не должна изменять состояние игры, она лишь определяет завершение игры. Её нужно использовать где-то в другом месте, скорее всего, после успешного размещения очередного флага (потому что открытие клетки либо однозначно завершает игру взрывом, либо однозначно продолжает её):

>func _on_flag_placed() -> void:


>_ if _is_game_over():


>_ _ emit_signal("game_over")



...а вообще-то, можно сделать ещё проще: совсем избавиться от пробега по каким-либо массивам. Лол, даже не подумал об этом изначально. Короче:

>func _on_flag_placed(cell_id: int) -> void:


>_ match field[cell_id]:


>_ _ EMPTY:


>_ _ _ flag_count += 1


>_ _ _ field[cell_id] = FLAG_EMPTY


>_ _ _ game_state = WRONG_FLAG


># бла-бла-бла, все состояния клеток обрабатываем...


>_ if flag_count == mine_count and game_state != WRONG_FLAG:


>_ _ emit_signal("game_over")


Видишь, нам не нужно обрабатывать всё поле после каждого клика, нам достаточно изменять клетку, по которой кликнули, число установленных флагов и состояние игры - корректно установлены флаги (только на минах) или нет (на пустых клетках). Итого избавились сразу и от Dictionary, и от лишнего прохода по каким-либо массивам, максимально оптимизировав игру.

Как же я хорош, как мощны мои коды...
198 789987
>>89978

>после успешного размещения очередного флага


>открытие клетки либо однозначно завершает игру взрывом, либо однозначно продолжает её


Эээ, чёт я конкретно тупанул. Да, в классическом Сапёре завершение игры определяется кликом по клетке, а не размещением флага. Более того, число флагов не обязательно должно соответствовать числу мин: обычно стоит ограничитель на максимальное число флагов, но все флаги устанавливать не нужно, можно вообще пройти игру без использования флагов, просто прокликав те клетки, которые точно не заминированы. Также не совсем ясен вопрос с автоматическим открытием больших скоплений пустых клеток после некоторых кликов... Но, наверное, последнее решается алгоритмом заливки, которая не основана на переборе всех ячеек массива. Так что опять же можно обойтись без лишних циклов, просто код будет выглядеть немного иначе, чем то, что я набросал выше.

Месяц назад хотел сделать свой вариант Сапёра, с сюжетом и спрайтами, но энергии хватило только на спрайты и сюжет - до создания игровой логики я не дотянул, а потом интерес пропал.
199 790044
Кто-то чета делает на альфе 4 версии? Или там вообще нихуя невозможно что-то поделать из-за багов? Рендор там заебись, вот только я не ебу, насколько профитно уже сейчас начинать переносить\писать на ней
200 790058
Предположим, я делаю скелет 3D персонажа в Blender.
1. Что будет, если я сделаю сначала примитивные руки с двумя пальцами и анимацию, а потом добавлю остальные пальцы? Анимацию придётся с нуля переделывать или только исправить?
2. Насколько сильно влияет число костей на производительность игры? Я через какой-то формат импортировал, так в Годо вместо каждой кости получилась отдельная нода. Потом я нашёл ноду Skeleton, она вроде появляется при импорте gltf, но всё равно беспокоит потеря производительности на кость.
3. Я правильно понял, что чем меньше костей в скелете, тем больше персонажей может быть одновременно на экране? На какое количество костей ориентироваться в гуманоиде, если планируется несколько десятков человечков в одной сцене?
4. Если импортировать скелет после Rigify, будет лишний мусор в Годо сцене? Ригифи создаёт какую-то странную кучу лишних блоков и каких-то данных в скелете, не понимаю, как всё это отделить от скелета при экспорте. Так что делаю пока без ригифи...
201 790061
>>90044

>насколько профитно уже сейчас начинать переносить\писать на ней


В официальной новости сказано примерно так: переносить большие проекты на альфу не следует, потому что до беты API движка может существенно измениться, и тогда придётся переделывать всё ещё раз. Вот когда начнётся бета, тогда будет "feature freeze" и все изменения будут направлены только на фикс багов - на бету уже можно будет переносить большие проекты. Однако всё-таки просят попробовать портировать что-нибудь на альфу, чтобы оценить движок на реальном проекте, но это имеет смысл только если ты будешь багрепорты создавать. Короче, серьёзно что-то делать пока не стоит.

>>90047 (Del)

>Редактор 4 падучий


Да, это так, но вроде терпимо (3.4.2 тоже падает).

>аддонов нет


Разве? Вроде уже что-то пишут на 4.х.

>писать все террейны, растительность, контроллеры самому


Не писать, а портировать! У тебя же всё это уже есть (должно быть), своё, самодельное, остаётся только API поменять. Плохо только тем, кто уже несколько лет ждёт релиза 4.0 и даже не притрагивался к 3.х, вот у них вообще ничего нет, это да.

>А что там с рендером по сравнению с 3?


Есть батчинг в 3D, автоматические LODы и окклюжн кулинг. Ну, как минимум батчинг уже работает, остальное не тестил. Также заметил новые настройки в Environment. В официальном блоге писали, что масштабируемость вулкана выше, т.е. несмотря на высокую нагрузку маленькой сцены большая сцена будет производительнее, но как это протестировать - непонятно. Как минимум батчинг повышает фпс, это точно, у меня 1000 кубов выдавали 1000 фпс за 2 дроуколла.
202 790063
>>90060 (Del)

>Палец будет привязан к ладони, т.е. неанимированный палец просто двигается вместе с ней, логично?


Да, я просто думал, что изменение рига полностью сбрасывает все данные по анимации (ожидаемо, учитывая сложность 3D).

>Думаю моделек 50 NPC и моделек 10 персонажей норм потянет


Ты имеешь в виду, что у игровых персонажей выше детализация меша, чем у неигровых? В противном случае не вижу причины, по которой неигровых можно добавить больше, чем игровых. С мешем пока вообще не ясно, что делать, теперь думаю сначала скелет с анимациями сделать, а меши потом заменять на более достойные, а то я задолбался каждый раз с нуля статичный меш переделывать (потому что визуально не нравится или имеет косяки геометрии), ни разу до стадии анимации не доходил (кроме пары случаев много лет назад, не помню уже ничего).

>Если будешь использовать физику типа рэгдоллов, придется использовать и те и те по любому.


Это я понимаю. Но рэгдолл вроде бы спавнится только по необходимости, т.е. не обязательно висит в сцене всё время.

>скелет для игры отдельно, навесы в блендере для анимирования отдельно


Понятно, спасибо. Как же лень смотреть видеотуториалы... Вот раньше умели делать текстовые уроки, а теперь разучились.
94996797p0.png5 Мб, 2307x3800
203 790070
>>90047 (Del)

>А что там с рендером


Вулкан же
>>90061
Понял, спасибо. Тогда буду по части нагружать жирными модельками движок, дабы хотя бы поглядеть производительность.
204 790079
>>90078 (Del)
Ничего там не появилось, кроме лайтмап, но этого достаточно
205 790085
>>90061

> Не писать, а портировать!


> У тебя же всё это уже есть (должно быть), своё, самодельное, остаётся только API поменять. Плохо только тем, кто уже несколько лет ждёт релиза 4.0 и даже не притрагивался к 3.х, вот у них вообще ничего нет, это да.


Частично двачую. Контроллеры свои, да. Тем более, контроллер (управления персонажем же имеется ввиду?) - это штука сугубо индивидуальная, интимная. Он создаёт основу впечатлений от игры вообще. Если он будет "как где-то", то вся игра будет "как что-то".
А вот террейн самодельный я ебал писать. Лучше Зилана не сделаю.
206 790089
>>90087 (Del)

> джоннироудровским


Но ведь он у тебя наверняка допилен своими фишками и абилками, достаётся за полсекунды, в руке лежит как влитой?
platform4.gif701 Кб, 1878x999
207 790133
>>89766
Полностью перенастроил всю физику и убрал следящую камеру. Теперь персонаж не так быстро бегает и высоко прыгает, но это позволит мне строить уровни в один экран.

ib4: клон селесты? Да
208 790164
>>90133
Сделал вот такие пилы при помощи path2d. Цепь генерируется автоматически из точек path2d. Все гениальное просто)
209 790170
>>90133

>убрал следящую камеру. Теперь персонаж не так быстро бегает и высоко прыгает


Имхо, убил всю динамику, +100 к унылости.

>позволит мне строить уровни в один экран


Зачем, почему? Помни, что разрешения экрана у всех разные, попытка вписать уровень чётко в экран может выглядеть не очень.

>>90085

>террейн самодельный


Я свой делаю, т.к. хочу что-то необычное, пусть и тайловое.

>>90078 (Del)

>Что вулкан дает рендеру?


Ну почитай разницу между вулканом и опенгл в целом, вне контекста игровых движков. Вулкан делает Кронос, который же развивал опенгл. По сути вулкан - наследник/логическое продолжение опенгл под новым названием и с другим апи. В целом, как я слышал, у вулкана более гибкий пайплайн, выше производительность и больше возможностей, чем у последних версий опенгл.

>>90067 (Del)

>У неигровых костей пальцев вообще может не быть.


Я хочу чтоб игровые от неигровых ничем физически не отличались, кроме "мозгов". Убирать пальцы можно разве что в качестве LOD для моделек на расстоянии от камеры, но это только увеличивает количество нод (даже если они будут вне дерева сцены). А рэгдоллу пальцы вообще никогда не нужны (наверное).
platform6.gif1,3 Мб, 1878x999
210 790183
>>90164
Как-то так. Теперь буду клепать уровни
211 790188
>>90171 (Del)

>50 костей на волосы, 50 костей на юбку


А что делать, если нужна кастомизация персонажа? Т.е. и юбку, и волосы можно заменить чем-то другим. В идеале все персонажи должны иметь возможность выглядеть одинаково. Честно говоря, пока ты не упомянул - вообще не задумывался о костях в одежде и волосах, планировал делать их статичными.

>она стоит и проигрывает свои две анимации


У меня она должна быть полностью функциональна как игровой персонаж, включая инвентарь, крафтинг и тому подобное. Не вижу смысла делать очередную унылую РПГ с глупыми статистами.
212 790215
>>90188

>У меня она должна быть полностью функциональна как игровой персонаж, включая инвентарь, крафтинг и тому подобное.


Ох чел. Я сейчас подобное пилю: любой неигровой персонаж может быть игровым, если перекинуть на него сигналы с контроллера. Это я в двадэ, и уже довольно геморно реализовывать всё с заделом на такую вот универсальность. А главная проблема возникает при попытке реализовать АИ. Всё-таки искусственному идиоту гораздо сподручнее иметь прямое, порой даже читерное управление персонажами.
мимо
213 790228
>>90170

> хочу что-то необычное, пусть и тайловое


Тайлы это двадэ, в тридэ нет тайлов, в тридэ - блоки, вокселы. Воксельный террейн есть у Зилана. Правда его надо конпелировать с движком, но тебя же это не остановит?
214 790229
>>90215

> Я сейчас подобное пилю: любой неигровой персонаж может быть игровым, если перекинуть на него сигналы с контроллера. Это я в двадэ, и уже довольно геморно реализовывать всё с заделом на такую вот универсальность. А главная проблема возникает при попытке реализовать АИ. Всё-таки искусственному идиоту гораздо сподручнее иметь прямое, порой даже читерное управление персонажами.


Эт я удачно зашёл. Помощь нужна? Сам хочу такое реализовать, но нахожусь пока что на этапе продумывания архитектуры.
215 790303
>>90229

>Помощь нужна?


Да не, какая тут помощь. Нынешний проект достаточно простой, чтобы его целиком самостоятельно сделать. А вот следующий, если этот удастся, уже надо будет коллабиться, там задумка более масштабная.
216 790337
>>90319 (Del)
C фильтрацией мышки поработай. Дёрганая она у тебя.
217 790372
>>90215

>Всё-таки искусственному идиоту гораздо сподручнее иметь прямое, порой даже читерное управление персонажами.


С одной стороны да, а с другой — определённый уровень унификации тоже нужен: всё-таки полоска ХП у всех должна быть и работать должна одинаково. А если юнитами управляет не WSAD с клавиатуры, а навигация из своей ноды, то тут вообще всё хорошо. Либо игрок выдаёт тебе точку, куда ты идёшь, и направление, куда машешь скиллшотом, либо то же самое делает ИИ.
А вообще, делайте игры с непрямым контролем, а то я опять свой сейв в Majesty продолбал.
218 790400
>>90372

> делайте игры с непрямым контролем


Туториал бы...
219 790412
>>90400
Majesty — твой туториал, и Dungeon Keeper.
220 790431
Кто мне там советовал юзать StyleBoxTexture? А я-то думал, что я тупой. Оказалось нет, оно действительно НЕ РАБОТАЕТ по принципу NinePatchRect. Ну, то есть, в глес2 не работает. А глес3 я не использую, потому что там батчинга нет (или уже есть?) https://github.com/godotengine/godot/issues/35186
1644487076093.png17 Кб, 606x135
221 790468
>>90431

> НЕ РАБОТАЕТ


Печально. Ну штош. Жди пока заработает.

> А глес3 я не использую, потому что там батчинга нет (или уже есть?)


Пишет, что есть.
222 790475
>>90431

>там батчинга нет


3D нет (только в 4.0 на вулкане), в 2D давно всё есть.

>>90400

>>игры с непрямым контролем


>Туториал бы...


Просто сохраняешь в памяти персонажа метку, которую поставил игрок или ИИ, и дальше в дело в ступает система навигации. Как использовать встроенную навигацию - есть туториалы. Но можно и свою собственную написать, на это тоже туториалы должны быть, в зависимости от алгоритма/архитектуры уровней. Глянь A-star, если твоя карта тайловая или может быть представлена матрицей.

>>90337

>C фильтрацией мышки поработай. Дёрганая


Скорее всего это не мышка дёрганная, а у него вещественные до целых чисел округляются, либо он обрабатывает движение мышки в _process вместо _input. У меня было точно такое же дёргание, пока я не нашёл место, где сохраняю float в int.

>>90338 (Del)
Дело не в твоей мышке, а в дискретности обработчика движений мышки в твоей игре. Изменения положения мышки должны накапливаться между кадрами и храниться как вещественные числа, чтобы не было скачков строго по пикселям.
223 790479
>>90228

>Тайлы это двадэ, в тридэ нет тайлов


Если весь мир можно представить как 2D сетку блоков, то эти блоки можно называть тайлами, даже если мир 3D.
https://ru.wikipedia.org/wiki/Тайловая_графика#Тайл_—_элемент_разбиения

>в тридэ - блоки, вокселы


Блоки и воксели - разные вещи.

>Воксельный террейн


Не хочу воксельный, у него свои проблемы.

>>90215

>любой неигровой персонаж может быть игровым, если перекинуть на него сигналы с контроллера


>гораздо сподручнее иметь прямое, порой даже читерное управление персонажами


У меня персонаж игрока и персонаж с ИИ имеют общего предка. Как будет реализовываться ИИ - дело десятое, оно не зависит от контроллера персонажа игрока. Хотя, да, можно было бы сделать композицию вместо наследования, как-то не подумал. Ну а сложность реализации ИИ в 3D мне известна, но мне не нужно что-то сверхсложное, достаточно по вейпойнтам ходить.
224 790487
Попытался сделать аналог .duplicate(), который есть у Array и Dictionary, в своём классе, наследнике Reference:

>Parser Error: Using own name in class file is not allowed (creates a cyclic reference)


А на Pascal я такое с лёгкостью делал...
Штош, придётся ждать 4.0:
https://github.com/godotengine/godot-proposals/issues/460
Алсо задолбался ошибками, которые возникают в скрипте, который использует другой скрипт, если тот другой скрипт как-то неправильно распарсился. Помогает перезагрузка всего проекта...
225 790494
>>90487
Нашёл решение:
https://godotengine.org/qa/14364/how-to-duplicate-a-reference
Должно помочь get_script().new():
https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-get-script
Неужели я искал решение целый час? Нет, я играл в игру.
226 790496
>>90494
Эээ... Или будет лучше наследоваться от Resource:
https://docs.godotengine.org/en/stable/classes/class_resource.html#class-resource-method-duplicate
Хотя duplicate() копирует только экспортированные поля...

>>90479

>композицию вместо наследования


Интересно, можно ли сделать контроллер персонажа на базе Resource, чтобы можно было вставлять его в ноду KinematicBody через параметры в инспекторе?.. Хм, с ИИ должно сработать, а вот на счёт игрового персонажа сомневаюсь - у Resource нет метода _input, следовательно, напрямую получать ввод пользователя он не может.
227 790504
>>90487

> наследнике Reference


>>90496

> Или будет лучше наследоваться от Resource


А ты зачем оттуда наследуешься? Я как-то наследовался от референса, потому что мои скрипты мне нужно было создавать и уничтожать пачками, и чтобы не париться с их высвобождением, я наследовался от референса, и отдал их высвобождение на откуп сборщику мусора. А ты? Или просто ебанул не думая по гайдам из интернетов, как вы, паскалисты любите?
Наследуйся от Object и не еби мозги.
228 790529
>>90504

>А ты зачем оттуда наследуешься?


Как это - зачем? Чтобы не было инвалидных ссылок и не пришлось париться с тем, где и когда вызывать free().

>на откуп сборщику мусора


Сборщик мусора только в коде на C# будет скапливать объекты и освобождать их по мере накопления. В коде на GDScript наследники Reference освобождаются сразу, как только число ссылок на них станет равно 0. По крайней мере я так понял:
https://docs.godotengine.org/en/stable/classes/class_reference.html

>Или просто ебанул не думая по гайдам из интернетов


Я долго думал, читал API и эту статью:
https://docs.godotengine.org/en/stable/tutorials/best_practices/node_alternatives.html

>как вы, паскалисты любите


Вот не надо обобщать, я с самого начала на Паскале много экспериментировал и писал велосипеды всю дорогу, никогда не любил копировать готовые куски кода из интернета или использовать готовые библиотеки. Всегда сначала пытаюсь сделать сам, и только если что-то совсем не получается - ищу подсказки в интернете. А всякие видеотуториалы вообще ненавижу смотреть. В Годо, кстати, было тяжело вкатиться как раз потому, что пытался сам открыть редактор и сразу без подсказок что-нибудь делать - к сожалению, без подсказок полностью с нуля освоиться в Годо невозможно, нужно читать официальное руководство как минимум.

>Наследуйся от Object и не еби мозги.


Лол, это как раз от Object будет головная боль с утечками памяти и инвалидными ссылками, зачем мне этот геморрой? Тем более если я хочу иметь duplicate() и даже, быть может, доступ к экспортируемым полям через инспектор. В том же Delphi/Lazarus тоже есть инспектор и есть возможность создавать свои компоненты, но я этим, к сожалению, почти не пользовался из-за сложностей создания и установки (в Lazarus вообще перекомпилировать редактор нужно, а это хоть и очень быстро, но всё-таки барьер). А так, компоненты форм - это гениальное изобретение, если им правильно пользоваться. Мне Godot нравится в том числе похожестью редактора на Delphi/Lazarus, в отличие от упоротого инспектора Unity, в котором ничего не найдёшь при всём желании.
228 790529
>>90504

>А ты зачем оттуда наследуешься?


Как это - зачем? Чтобы не было инвалидных ссылок и не пришлось париться с тем, где и когда вызывать free().

>на откуп сборщику мусора


Сборщик мусора только в коде на C# будет скапливать объекты и освобождать их по мере накопления. В коде на GDScript наследники Reference освобождаются сразу, как только число ссылок на них станет равно 0. По крайней мере я так понял:
https://docs.godotengine.org/en/stable/classes/class_reference.html

>Или просто ебанул не думая по гайдам из интернетов


Я долго думал, читал API и эту статью:
https://docs.godotengine.org/en/stable/tutorials/best_practices/node_alternatives.html

>как вы, паскалисты любите


Вот не надо обобщать, я с самого начала на Паскале много экспериментировал и писал велосипеды всю дорогу, никогда не любил копировать готовые куски кода из интернета или использовать готовые библиотеки. Всегда сначала пытаюсь сделать сам, и только если что-то совсем не получается - ищу подсказки в интернете. А всякие видеотуториалы вообще ненавижу смотреть. В Годо, кстати, было тяжело вкатиться как раз потому, что пытался сам открыть редактор и сразу без подсказок что-нибудь делать - к сожалению, без подсказок полностью с нуля освоиться в Годо невозможно, нужно читать официальное руководство как минимум.

>Наследуйся от Object и не еби мозги.


Лол, это как раз от Object будет головная боль с утечками памяти и инвалидными ссылками, зачем мне этот геморрой? Тем более если я хочу иметь duplicate() и даже, быть может, доступ к экспортируемым полям через инспектор. В том же Delphi/Lazarus тоже есть инспектор и есть возможность создавать свои компоненты, но я этим, к сожалению, почти не пользовался из-за сложностей создания и установки (в Lazarus вообще перекомпилировать редактор нужно, а это хоть и очень быстро, но всё-таки барьер). А так, компоненты форм - это гениальное изобретение, если им правильно пользоваться. Мне Godot нравится в том числе похожестью редактора на Delphi/Lazarus, в отличие от упоротого инспектора Unity, в котором ничего не найдёшь при всём желании.
229 790584
>>90504

>Или просто ебанул не думая по гайдам из интернетов, как вы, паскалисты любите?


Я думал, у Паскальщиков наоборот, репутация самых отмороженных велосипедистов. Во-первых ему в школе учат, когда не до туториалов, а во-вторых на нём много всяких олимпиадных оболтусов байтоёбство пишут.
230 790600
Как остановить паралелльность циклов из коробки в годоте?
231 790603
>>90584
Скорее всего он судит по нытикам на форумах, которые копипастят код с рандомных сайтов, не понимая, что он делает, а потом создают пост на форуме типа "как исправить ошибку". Хотя чаще всего создают посты вида "как решить задачу" и ждут готового кода. Однако это всё не паскальщики, это школота и студентота, которой программирование нахрен не нужно, они учатся на каких-нибудь гуманитариев, а в школе/вузе информатику заставляют сдавать. Настоящие паскальщики вообще редко задают вопросы на форумах, потому что все ответы на вопросы есть в руководствах и прочих книгах, а решение каких-то популярных задач можно подсмотреть на другом императивном языке.
232 790605
>>90600

>остановить паралелльность циклов из коробки


В каком смысле остановить? Из коробки и по умолчанию почти всё в Годо происходит последовательно, в один поток на одном ядре. В настройках можно переключить графику в отдельный поток, но исполнение скриптов всегда в одном потоке. Можно создавать из кода отдельные потоки, но это делается строго вручную, а не автоматически. Все _process и _physics_process выполняются строго последовательно, по порядку расположения нод в дереве сцены.
233 790611
>>90607 (Del)

>одному из них делать set_process(false) и обмазывать семафорами


Зачем, если можно просто перенести код из _process в отдельный метод, который вызывать (напрямую или с помощью сигналов, обработчик сигнала вызывается в момент излучения сигнала) из _process другого объекта?
234 790626
>>90605
В годо функции выполняются параллельно, ты это заметишь.
Если ты напишешь
for i in range(50):
println(i);
func println(i)->void:
yield(5sec);

>>90607 (Del)
Я не написал process. Я написал именно что циклы. Годо оптимизирует за вас работу и паралелит выполнение кода без вашего на то знания. Если функция очень тяжелая в цикле или в другой функции, годо создает отдельный тред, оставляя на него выполнение функции, и идет выполнять функции дальше до тех пор, пока не потребуется результат работы скипнутой функции.
235 790632
>>90626

>функции выполняются параллельно


Нет, последовательно, если не использовать потоки.

>yield(5sec);


Во-первых, что значит "5sec"? Функция yield() не принимает времени, это не аналог sleep() или delay() из других языков.
Во-вторых, yield() прерывает выполнение функции, возвращая интерпретатор к вызвавшей её функции. Выполнение прерванной функции может быть продолжено с помощью .resume(), если yield() вызвана без параметров, или путём получения сигнала, который был указан в параметрах yield(). В любом случае всё выполнение происходит последовательно, а не параллельно.
Подробнее: https://gdscript.com/solutions/coroutines-and-yield/

>Годо оптимизирует за вас работу


Возможно, в каком-то виде - да.

>паралелит выполнение кода без вашего на то знания


Нет, ничего он не параллелит сам по себе. Из-за его упорной последовательности он по умолчанию загружает на 100% одно ядро многоядерного процессора и из-за этого игра может тормозить. Ты сам должен распределять свой тяжёлый код на несколько потоков, чтобы рациональнее нагружать многоядерные процессоры.

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


Пруфы без yield() будут или нет? Покажи свой реальный код, который у тебя по какой-то причине "параллелится" без спроса.

Самое смешное, что мой код генерации мира занимает порой 30+ секунд, что полностью замораживает игру (окошко мутнеет и при клике по нему Windows предлагает закрыть зависшую программу), при этом грузится, разумеется, только одно из четырёх ядер. Я пытаюсь распределить нагрузку по кадрам, но, тем не менее, долгие шаги (500+ мс) всё равно провоцируют "заморозку". Если так дальше пойдёт, придётся, наверное, реально в отдельном потоке делать генерацию, т.к. хочется видеть на экране живой прогрессбар, а не заморозку всей игры на неопределённое число секунд...

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

Подробнее про определение "тяжёлой функции":
https://ru.wikipedia.org/wiki/Проблема_остановки
tl;dr: невозможно математически определить, остановится ли когда-либо алгоритм или нет. Т.е. если твоя программа содержит бесконечный цикл, другая программа не может этого узнать без использования эвристик, которые не покрывают всех возможных случаев, потому что основываются лишь на опыте. Ну и следовательно невозможно в общем случае определить, сколько итераций будет в цикле или сколь затратными будет каждая итерация. Поэтому такие оптимизации просто невозможно сделать для общего случая.
235 790632
>>90626

>функции выполняются параллельно


Нет, последовательно, если не использовать потоки.

>yield(5sec);


Во-первых, что значит "5sec"? Функция yield() не принимает времени, это не аналог sleep() или delay() из других языков.
Во-вторых, yield() прерывает выполнение функции, возвращая интерпретатор к вызвавшей её функции. Выполнение прерванной функции может быть продолжено с помощью .resume(), если yield() вызвана без параметров, или путём получения сигнала, который был указан в параметрах yield(). В любом случае всё выполнение происходит последовательно, а не параллельно.
Подробнее: https://gdscript.com/solutions/coroutines-and-yield/

>Годо оптимизирует за вас работу


Возможно, в каком-то виде - да.

>паралелит выполнение кода без вашего на то знания


Нет, ничего он не параллелит сам по себе. Из-за его упорной последовательности он по умолчанию загружает на 100% одно ядро многоядерного процессора и из-за этого игра может тормозить. Ты сам должен распределять свой тяжёлый код на несколько потоков, чтобы рациональнее нагружать многоядерные процессоры.

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


Пруфы без yield() будут или нет? Покажи свой реальный код, который у тебя по какой-то причине "параллелится" без спроса.

Самое смешное, что мой код генерации мира занимает порой 30+ секунд, что полностью замораживает игру (окошко мутнеет и при клике по нему Windows предлагает закрыть зависшую программу), при этом грузится, разумеется, только одно из четырёх ядер. Я пытаюсь распределить нагрузку по кадрам, но, тем не менее, долгие шаги (500+ мс) всё равно провоцируют "заморозку". Если так дальше пойдёт, придётся, наверное, реально в отдельном потоке делать генерацию, т.к. хочется видеть на экране живой прогрессбар, а не заморозку всей игры на неопределённое число секунд...

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

Подробнее про определение "тяжёлой функции":
https://ru.wikipedia.org/wiki/Проблема_остановки
tl;dr: невозможно математически определить, остановится ли когда-либо алгоритм или нет. Т.е. если твоя программа содержит бесконечный цикл, другая программа не может этого узнать без использования эвристик, которые не покрывают всех возможных случаев, потому что основываются лишь на опыте. Ну и следовательно невозможно в общем случае определить, сколько итераций будет в цикле или сколь затратными будет каждая итерация. Поэтому такие оптимизации просто невозможно сделать для общего случая.
236 790651
>>90183
Реализовал срезание углов.
Оно срабатывает в двух случаях:
1) Если персонаж двигается вверх, тогда его двигает по горизонтали
2) Если персонаж в дэше, тогда его может подвинуть еще и по вертикали

По поводу физики:
Пришел к тому, что самое лучшее решение - высчитывать физику персонажа по формулам, а не пытаться брутфорсить в поисках приятных значений. Теперь я указываю длину прыжка, время до апекса(Когда velocity.y == 0), высоту прыжка. По формуле уже получаю гравитацию, силу прыжка, скорость героя и другие параметры. Позже хочу добавить уменьшение гравитации в нулевой точке падения и срезание прыжка, как было до этого.
2 шаблона.png3 Кб, 450x450
237 790687
Начал делать ОО генератор, набросал два шаблона (просто круг и круг с дыркой) и чёт совсем приуныл... Получается, что если следовать этому пути, потребуется описать много шаблонов и их параметров, и я буду +/- узнавать то, что делает такой генератор, т.е. с первого взгляда видеть все эти шаблоны.

Собственно, в чём проблема... Я-то изначально планировал генератор мира как "волшебную кнопку", которая каждый раз создаёт что-то уникальное. Но если использовать какие-либо шаблоны, то даже с добавлением в эти шаблоны некоторого хаоса все результаты одного шаблона будут примерно похожи друг на друга. А если хаоса слишком много, то от таких шаблонов никакой пользы, потому что их становится сложно контролировать.

Короче, мне намного больше нравился тот вариант, где я просто рандомно раскидываю круги разных размеров и получаю на выходе практически непредсказуемую карту, которая может принимать реально интересные и неожиданные формы, несмотря на всю примитивность базового алгоритма. С тем генератором хоть и могли получаться неиграбельные варианты (почти нет дорог, суша порвана на мелкие клочки), но каждая генерация могла чем-то удивить и порадовать, а здесь у меня тупо выбор между двумя шаблонами и практически ничего не значащие декорации по краю.

Судя по всему, никак не избежать создания тайлового детектора подходящих участков суши для размещения частей города и прочих структур. Что так, что эдак, всё равно нужно вычислять подходящие места, но без шаблонов суша будет хотя бы менее предсказуемой.
238 790696
>>90687
Хотелось бы взглянуть на твою реализацию генератора. Если я правильно понял, у тебя клеточный автомат (если вокруг клетки больше N клеток, она "умирает", если меньше M, то добавляет новую). Но в большинстве известных мне клеточных автоматов (игра жизь лол) логика бинарная: живая клетка = 1, мёртвая = 0.

А что если тебе модифицировать генератор так, чтобы в генерации участвовали несколько конкурирующих цветов клеток? Каждый цвет символизирует биом или тип местности. Или у тебя так и есть?
Если грамотно задать правила генерации, при которых описаны переходы из одних биомов в другие, то можно получить интересные результаты. В том числе эти мифические метаданные, о которых говорили выше.
Пример правила чисто с дивана: если скажем в окрестности коричневой клетки (земля) мало бирюзовых клеток (пресная вода), то она превращается в желтую клетку (пустыня).
первый успешный генератор.png336 Кб, 1440x850
239 790697
>>90689 (Del)

>генерится, подстраивая под собой землю


Думал о таком... Чтобы этот подход сработал, город должен иметь структуру, которую можно было бы расположить в пустоте, а затем нарастить вокруг этой структуры все остальные объекты. Но у меня почти с самого начала город встраивался в форму суши, т.е. у "города" никакой структуры нет. Я думал, так лучше, т.к. реалистичнее (города строятся в какой-то местности, а не наоборот, за очень редким исключением), но, возможно, я ошибся.

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

Вспомнил... Мой первый успешный генератор целого города работал (прошлым летом) примерно так:
- рисуем сетку дорог, вписанную в окружность;
- вырезаем случайные участки дорог;
- сокращаем тупиковые обрезки дорог;
- наращиваем вокруг дорог сушу (!);
- выстраиваем домики вокруг дорог;
- потом я ещё песок наращивал вокруг суши...
Получался город в форме кляксы с пикрила. Прикольно, конечно, мне даже немножко нравилось, но хотелось чего-то кроме круглой кляксы. Вот тогда-то я и загорелся идеей сначала делать сушу, а уже по суше прокладывать дороги, "всё как в жизни". А мог просто изменить изначальную генерацию "сетка в круге" на что-то другое и затем усилить наращивание суши (чтобы не было "кляксы"). Теоретически, я бы мог даже избежать разрывов в сети дорог, которая меня напрягает с самого начала второго генератора (дороги по суше, разрыв в суше = разрыв в сети дорог, если не придумать какой-то мост, но сначала этот самый разрыв нужно найти).

Да... Нужно обязательно попробовать такой подход. Спасибо, что натолкнул меня на эту мысль, а то я уже забыл, с чего начинал и какую цель изначально преследовал. Город >> ландшафт, всё так и должно быть, а то я зациклился на необитаемых островах каких-то, даже симулировать вулканическую активность собирался, лол.
первый успешный генератор.png336 Кб, 1440x850
239 790697
>>90689 (Del)

>генерится, подстраивая под собой землю


Думал о таком... Чтобы этот подход сработал, город должен иметь структуру, которую можно было бы расположить в пустоте, а затем нарастить вокруг этой структуры все остальные объекты. Но у меня почти с самого начала город встраивался в форму суши, т.е. у "города" никакой структуры нет. Я думал, так лучше, т.к. реалистичнее (города строятся в какой-то местности, а не наоборот, за очень редким исключением), но, возможно, я ошибся.

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

Вспомнил... Мой первый успешный генератор целого города работал (прошлым летом) примерно так:
- рисуем сетку дорог, вписанную в окружность;
- вырезаем случайные участки дорог;
- сокращаем тупиковые обрезки дорог;
- наращиваем вокруг дорог сушу (!);
- выстраиваем домики вокруг дорог;
- потом я ещё песок наращивал вокруг суши...
Получался город в форме кляксы с пикрила. Прикольно, конечно, мне даже немножко нравилось, но хотелось чего-то кроме круглой кляксы. Вот тогда-то я и загорелся идеей сначала делать сушу, а уже по суше прокладывать дороги, "всё как в жизни". А мог просто изменить изначальную генерацию "сетка в круге" на что-то другое и затем усилить наращивание суши (чтобы не было "кляксы"). Теоретически, я бы мог даже избежать разрывов в сети дорог, которая меня напрягает с самого начала второго генератора (дороги по суше, разрыв в суше = разрыв в сети дорог, если не придумать какой-то мост, но сначала этот самый разрыв нужно найти).

Да... Нужно обязательно попробовать такой подход. Спасибо, что натолкнул меня на эту мысль, а то я уже забыл, с чего начинал и какую цель изначально преследовал. Город >> ландшафт, всё так и должно быть, а то я зациклился на необитаемых островах каких-то, даже симулировать вулканическую активность собирался, лол.
240 790698
Пацаны, я познал дзен ResourceInteractiveLoader'а и дико доволен. Но я зашёл ещё дальше и по его образцу написал свой интерактивный загрузчик сейвов. Это вообще космос!
Меня так прёт от полученного опыта, что спешу им поделиться. Может, кому понадобится.
1. Берём какой-то комплексный процесс и разбиваем его на стадии.
2. Если заранее знаем, сколько стадий (например, у нас массив, где каждая запись - это инфа о ноде, которую надо инстанцировать), то запоминаем, пригодится.
3. Пишем функцию poll, которая выполняет одну стадию, инкрементирует индекс стадии и возвращает еггог месседж: если ок. то OK, если всё закончилось, то ERR_FILE_EOF, ну и там ещё какие-нибудь ошибки можно предусмотреть.
4. А собсно всё. Теперь вне этого объекта где-нибудь создаём загрузочный экран.
5. Загрузочный экран в _process запускает маленький циклик. Запоминаем время OS.get_ticks_msec(), и в условии цикла while ставим, чтобы прошло не слишком много времени (в официальном туторе 100мсек). А в теле цикла у нас только poll() и обработка возвращаемых им ошибок.
6. А собсно всё. Пока от полла поучаем OK, продолжаем грузить. Можно в каждый вызов _process спрашивать у нашего объекта-загрузчика, сколько ему ещё грузить осталось, на основе этого рисовать полосу загрузки. Если полл говорит, что у него не ок, пишем нашему загрузочному экрану set_process(false). Полученный от полла eof означает, что всё загрузилось успешно.
7. Ну и у ResourceInteractiveLoader ещё после завершения загрузки надо получить загруженный ресурс через get_resource(). В моём загрузчике этого нет, потому что он не просто загружает сейв-файлы, но и сразу инстанцирует все игровые объекты.

Вооот. Крч клёвая штука.
241 790699
>>90698

>а собсно всё


>а собсно всё


Блин, так увлёкся, что не уследил за повествованием. Бывает.
242 790703
>>90698

> клеточный автомат


А почему сейв-файл такой большой, что его приходится по частям грузить?
243 790704
>>90703
Гринтекст левый прицепился.
244 790706
>>90698
У меня похожая система была реализована для визуализации огромной тайловой карты (отказался в пользу очередей чанков) и сейчас реализована в генераторе этой тайловой карты. Проблемы тут две: не всякий процесс можно/легко разбить на маленькие части и добавление промежутков значительно (иногда в разы) удлиняет время ожидания завершения процесса. В каких-то ситуациях лучше создать параллельный поток и ждать его завершения, чем разбивать один поток на этапы и выполнять их по очереди с рендерингом движка. Всё равно одноядерных процессоров по сути не существует, как минимум два ядра есть у всех, да и если бы были одноядерные - ОС лучше справится с симуляцией многопоточности, чем ты.
245 790719
>>90706

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


Несомненно. Но это другие процессы. Согласись, загрузка сейва или уровня - не такая ситуация.

>>90703

>А почему сейв-файл такой большой, что его приходится по частям грузить?


Сам сейв-файл не такой большой. Но после его загрузки нужно восстановить все находящиеся на уровне объекты - загрузить, инстанснуть, поставить на место и задать свойства. А вот это уже времени занимает немало.
246 790722
>>90719
Сейвы делаешь в точности по документации? Прямо движок-специфичную инфу туда ебошишь, как предлагает документация в нарушение принципов SOLID? Нирикаминдую, если так. Рикаминдую в сейв писать абстрагированную игра-специфичную инфу, например:

> {"level":"black_mesa", "health":98, "ammo":175}


Которую игра будет самостоятельно парсить и создавать внутриигровые объекты, а не создавать ноды по записанным, блять, в сейв-файл путям. Ужас какой-то, блять!
247 790723
>>90696

>в большинстве известных мне клеточных автоматов (игра жизь лол) логика бинарная


Мало клеточных автоматов видел, значит. Бинарные клетки всего в нескольких наиболее известных КА, в остальных чаще встречаются три и больше состояний - я видел и 16, и даже 256 состояний одной клетки. Ну, всё зависит от поставленных задач.

>если вокруг клетки больше N клеток, она "умирает", если меньше M, то добавляет новую


Мой клеточный автомат >>89957 предполагает применение любых правил к каждой клетке. При этом я в попытках генерировать карту чисто на КА (пример - пикрил) использовал сразу несколько правил, последовательно применяющихся к карте. Скажем, дороги на пикриле размещает тоже КА, но основа для размещения - делимость координат клетки на какое-то число, а не окружающие клетки. Собственно клеточные автоматы не обязательно симулируют живые организмы, они просто применяют простые правила к каждой клетке некоторого массива произвольной размерности.

>у тебя клеточный автомат


Здесь >>90687 клеточный автомат только создаёт береговую линию, превращая клетки травы, близкие к воде, в песок. Основа же - просто закрашивание окружностей одним типом блока (травой).

Здесь >>89499:
пик 1-2: клеточный автомат добавляет ровным кругам неровные очертания из песка, удаляет мелкие обрывки земли и песка, добавляет лес определённой плотности (чем дальше от воды и дорог - тем плотнее лес), также расставляет домики.
пик 3: один только клеточный автомат, стартующий с рандомно разбросанных клеток земли, в общем, как на пикриле.

Ну, здесь >>90697 я алгоритм уже описал, там клеточный автомат только наращивал траву и, позже, песок, расставлял домики и укорачивал тупиковые дороги. Высота домиков в этом варианте зависит от близости к центру карты, там что-то вроде графика функции y = x² (только в 3D), точно не помню.

На втором пикриле ещё я пытался сделать возвышенности - они тоже создаются клеточным автоматом, но уже не только по типам клеток, но ещё по смещению от уровня моря (0). Т.е. за первый проход поднимаются на единичку удалённые от воды клетки травы, за второй проход удалённые от нулевых высот клетки с единичной высотой поднимаются на вторую высоту и т.д.

>Каждый цвет символизирует биом или тип местности.


Биомы (как в майнкрафте) я так и не начал делать. Возможно, можно было бы сделать их в отдельном массиве, и потом использовать этот массив как трафарет, но сначала я хотел разобраться с общими очертаниями острова (или другого типа суши), прежде чем делить его на биомы.

>взглянуть на твою реализацию генератора


У меня там куча файлов разных версий, закомментированных участков кода и прочего мусора. В общем, проще на словах объяснить, чем показывать. Задавай конкретные вопросы.
247 790723
>>90696

>в большинстве известных мне клеточных автоматов (игра жизь лол) логика бинарная


Мало клеточных автоматов видел, значит. Бинарные клетки всего в нескольких наиболее известных КА, в остальных чаще встречаются три и больше состояний - я видел и 16, и даже 256 состояний одной клетки. Ну, всё зависит от поставленных задач.

>если вокруг клетки больше N клеток, она "умирает", если меньше M, то добавляет новую


Мой клеточный автомат >>89957 предполагает применение любых правил к каждой клетке. При этом я в попытках генерировать карту чисто на КА (пример - пикрил) использовал сразу несколько правил, последовательно применяющихся к карте. Скажем, дороги на пикриле размещает тоже КА, но основа для размещения - делимость координат клетки на какое-то число, а не окружающие клетки. Собственно клеточные автоматы не обязательно симулируют живые организмы, они просто применяют простые правила к каждой клетке некоторого массива произвольной размерности.

>у тебя клеточный автомат


Здесь >>90687 клеточный автомат только создаёт береговую линию, превращая клетки травы, близкие к воде, в песок. Основа же - просто закрашивание окружностей одним типом блока (травой).

Здесь >>89499:
пик 1-2: клеточный автомат добавляет ровным кругам неровные очертания из песка, удаляет мелкие обрывки земли и песка, добавляет лес определённой плотности (чем дальше от воды и дорог - тем плотнее лес), также расставляет домики.
пик 3: один только клеточный автомат, стартующий с рандомно разбросанных клеток земли, в общем, как на пикриле.

Ну, здесь >>90697 я алгоритм уже описал, там клеточный автомат только наращивал траву и, позже, песок, расставлял домики и укорачивал тупиковые дороги. Высота домиков в этом варианте зависит от близости к центру карты, там что-то вроде графика функции y = x² (только в 3D), точно не помню.

На втором пикриле ещё я пытался сделать возвышенности - они тоже создаются клеточным автоматом, но уже не только по типам клеток, но ещё по смещению от уровня моря (0). Т.е. за первый проход поднимаются на единичку удалённые от воды клетки травы, за второй проход удалённые от нулевых высот клетки с единичной высотой поднимаются на вторую высоту и т.д.

>Каждый цвет символизирует биом или тип местности.


Биомы (как в майнкрафте) я так и не начал делать. Возможно, можно было бы сделать их в отдельном массиве, и потом использовать этот массив как трафарет, но сначала я хотел разобраться с общими очертаниями острова (или другого типа суши), прежде чем делить его на биомы.

>взглянуть на твою реализацию генератора


У меня там куча файлов разных версий, закомментированных участков кода и прочего мусора. В общем, проще на словах объяснить, чем показывать. Задавай конкретные вопросы.
248 790730
>>90723

> Задавай конкретные вопросы.


Вот какая у меня мысль. Может проще было бы заюзать встроенный симпл-нойз для генерации основы? А потом клеточным автоматом по ней пройтись.
1644591706972.png215 Кб, 662x686
249 790737
>>90730
Выглядит симпатично. Правда тормозит пиздецки. Потому что надо с нойз-текстурой разбираться, а я лупанул втупую на канву миллиардами дроуколлов. Но это чисто для демонстрации.
1644592936732.png372 Кб, 666x801
250 790751
>>90737
C нойзом фантазия воще вдаль улетает, стоит только зацепиться. Можно сделать так. Поверх двадэ нойза накидать три псевдовысоты тридэ нойза и засуммировать в общий цвет. Получаются готовые случайные биомы. Полученную пикчу можно редуцировать до нужного количества цветов и вуаля.
251 790756
>>90730

>Может проще было бы заюзать встроенный симпл-нойз для генерации основы?


Я поверхностно изучал тему шума, и нашёл такое мнение, что шум используют все новички, восхищаясь результатами, но дальше банальных холмов продвинуться не могут... Типа шум - это для маленьких детей, взрослые люди используют другие методы. И мне кажется, так оно и есть. Шум даёт плавные градиенты между набором рандомных точек - а что дальше с этим делать-то?

Алсо шум, по-моему, даёт слишком однородную и однообразную картинку, какими бы плавными градиенты ни были. В Майнкрафте вот аж 5 разных карт с шумом комбинируются, чтобы определить биом и его геометрию - но получается какое-то однообразие. Сколько ни бегал по мирам Майнкрафта (именно в поиске чего-то интересного), только изредка встречаются забавные артефакты генерации, в остальном - "любая тарелка овсянки технически уникальна". Мне хотелось как-то избежать этого (овсянки), поэтому не хотелось начинать с градиентного шума.

Вот здесь >>90723 на первой картинке очень хорошо видна эта "овсянка", которая хоть и уникальна на всех 4 квадратах (если присмотреться, видно, что каждый квадрат замыкается сам на себя по краям, т.е. это 4 независимых карты), но на первый взгляд разницы вообще нет, будто это одна и та же картинка. С градиентным шумом будет примерно такая же картинка, независимо от постобработки. Хотелось бы этого как-то избежать...

>>90737

>Выглядит симпатично


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

>миллиардами дроуколлов


Можно через вьюпорт кэшировать в текстуру. Я так миникарту кэширую - одно время не мог понять, откуда лаги, пока не отключил отображение миникарты, после этого сделал вьюпорты.
252 790758
790751
Попробуй c = stepify(noise.get_noise_2d(x, y), 2/n)/2, где n это кол-во шагов, на которое поделить значение шума. Получатся ступеньки
253 790759
254 790761
>>90756

> Шум даёт плавные градиенты между набором рандомных точек - а что дальше с этим делать-то?


Пройтись твоим генератором, который к шуму добавит свои детали. Очевидно же.
White-noise-mv255-240x180.png42 Кб, 240x180
255 790763
>>90737
>>90751
Знаешь, что мне это напоминает? Пикрил. Это белый шум. Делается максимально просто, нужен только рандом:

>for x in size: for y in size: cell[x][y] = randi() % 2


Проблема белого шума как раз в однородности. Это просто бесформенная каша. Любой градиентный шум в своей основе - тот же белый шум, только растянутый, а промежутки заполнены градиентом, то есть вместо 0 1 0 1 будет 0.0 0.5 1.0 0.5 1.0, но ощущения от восприятия не меняются, каша остаётся кашей.

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

>>90761

>к шуму добавит свои детали


Придумать бы ещё, какие и как. И не проще ли избежать чего-то изначально, чем потом маскировать?
256 790879
>>90651
Три дня пытался заставить персонажа прилипать к двигающимся стенам. Ничего не работало. По итогу идеально сработал самый бредовый способ, который я оставил на последок. Я тупо поменял вектор гравитации и нормаль пола во время цепляния за стену.

Уже предвкушаю какие левелы можно с этим будет сделать
sage 257 790880
>>90763

>Знаешь, что мне это напоминает? Пикрил. Это белый шум.


Что ты несёшь, неуч? Это не белый шум, а градиентный. Сравни свою картинку и его.

>>90756

>ты разве не видишь эту однородную кашу


Посмотри на снимки со спутника гугл-карт, увидишь то же самое.
258 790887
>>90879

> Я тупо поменял вектор гравитации и нормаль пола во время цепляния за стену.


А если ты сделаешь вектор не ровно влево, а немного вниз, он будет слегка съезжать. А если ты сделаешь этот вектор по таймеру плавно поворачивающимся вниз, ты сделаешь усталость.
259 790914
>>90887

>А если ты сделаешь вектор не ровно влево, а немного вниз, он будет слегка съезжать



Таки нет. Съезжание это по сути перемещение вдоль стены. Когда персонаж ходит по полу, вектор гравитации же не меняется. Он просто умножается на дельту и добавляется к текущему вектору скорости.

Да и скатывание по стене и таймер усталости уже реализованы.
260 791055
>>90880

>>напоминает [белый шум]


>Это не белый шум


Ты глупенький? Я написал "напоминает", а не "является".

>Посмотри на снимки со спутника


То что ИРЛ Земля выглядит как засохшая и потом разбавленная водой овсяная каша меня нисколько не удивляет и не волнует. Я же игру хочу сделать, а не скопировать ИРЛ планету... С такой графикой, какую я могу сделать, ни о каком реализме не может быть и речи.

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

Иногда просто нужно делать два шага назад и осматривать то, что делаешь, чтобы не зарываться в бесполезные детали.
261 791072
>>91055

> я уже осознал, что такая генерация мира мне не нужна


В цепочке осознаний главное - не осознать, что такая игра уже есть, делать её не нужно, достаточно скачать и играть.
262 791092
>>91085 (Del)
Кстати, по этой причине я и пришёл сюда. У меня сгорел пердак от невозможности нормально настроить скайрим с модами. Сколько я форумов перелопатил. Ничего не помогало. А потом я осознал: хватить насиловать тесач, сделай свою игру.
263 791136
>>91085 (Del)

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


Гдачую.

>>91072

>такая игра уже есть, делать её не нужно, достаточно скачать и играть


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

>такая генерация мира мне не нужна


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

А вообще, это всё прокрастинация. Генерация мира мне вообще не так уж и нужна, но это позволяет оттягивать момент, когда я столкнусь с проблемами разработки ИИ. Я слабо представляю, что должен буду сделать, и поэтому избегаю начала работы над этим... Читал разные подходы и в т.ч. часто упоминаемый тут ГОАП, но это не помогает, т.к. ГОАП решает какие-то goals, которых у меня (моих ботов) пока нет. Да и с навигацией не знаю, что делать, я смог только научить двигаться от вейпойнта к вейпойнту, после чего забросил проект более чем на год, т.к. дальше вейпойнтов мысль не зашла.

Короче, нужно прекращать откладывать, сделать тестовую карту небольшого размера с тестовыми домиками и приступать к разработке жителей. А уже когда они будут более-менее готовы (хотя бы знать где пожрать и где поспать, чтобы не сдохнуть), можно думать над процедурным заполнением мира.
264 791145
Продолжаю расковыривать систему сохранения-загрузки.
Суть процесса такова:

> for node in get_tree().get_nodes_in_group("save"):


> > save_data.append(node.save())


Соответственно, функция save() прописывается для каждой ноды, которую мы хотим сохранять, и возвращает словарь, куда записывает все сохраняемые свойства, в том числе имя файла сцены, имя ноды и положение на дереве. Массив save_data мы и пишем в сейв-файл. Потом при загрузке, соответственно, проходим по массиву, загружаем каждую сцену, инстансим её, вставляем в дерево, переименовываем и вызываем в ней load_saved(data), чтобы она уже сама восстановила себя.
Это общий план сохранения для более-менее комплексных игр. Но он упирается в одну важную проблему: если родитель и потомок находятся в группе save, то нет гарантии, что загружаться они будут именно в таком порядке. А если сначала загрузится потомок, то его будет тупо некуда ставить на дереве. Как я предполагаю это решать (и даже уже получается):
1. Определить порядок:
а) Прописать в экспортной переменной или в самой функции save.
б) Автоматически определять при сохранении, проходя по родителям, сколько там выше по иерархии ещё их таких сохраняемых.
2. а) При загрузке проходить по всему массиву несколько раз, каждый проход загружать только те ноды, которые имеют соответствующую запись порядка.
б) При сохранении сразу записывать ноды в массив в нужном порядке.

Это то, что мне известно. А может быть, я не знаю какой-то супер-ультимативный способ? Или отстал от времени, и сейчас в тренде что-то иное? Или есть какие-то детали, упрощающие жизнь? Просветите, годаны.
265 791149
>>91145

>супер-ультимативный способ


Ты пытаешься изобрести золотой молоток.
https://ru.wikipedia.org/wiki/Золотой_молоток
Если тебе нужен универсальный способ, то он есть в Godot из коробки, это сохранение и загрузка упакованных сцен, целиком, втупую, со всеми вытекающими из этого последствиями. Зато супер универсально - подойдёт любой простой игре, у которой 3.5 ноды и ни одна из них не является сиротой.

Для более сложных игр нужны специализированные решения, которые не должны опираться на нодовую систему. Скажем, у тебя может быть менеджер уровня, который руководит расстановкой всех юнитов на карте - тебе не нужно сохранять позицию каждого юнита, достаточно только сохранить конкретные данные менеджера, которые он после загрузки использует для расстановки юнитов заново. Как он будет эти данные использовать, какие ноды создавать и в каком порядке - от системы сохранения и загрузки не зависит, от неё требуется только записать, а потом прочитать блок неких данных.

Вот я делаю большой открытый мир. Все данные о мире собраны в одном классе. Эти данные используют менеджер чанков и отдельный скрипт визуализации, чтобы отобразить эти данные в 3D виде (с помощью нод или без них - не важно). Таким образом, для сохранения и загрузки игры мне достаточно сохранить и загрузить эти данные о мире, а всё остальное сработает автоматически, потому что никак не зависит от системы сохранения мира. И я думаю, что такая кастомная система должна быть в любой относительно крупной игре, потому что на нодах сделать всё это было бы нереально.
platform15.gif6,8 Мб, 1496x911
266 791163
>>90879
Что-то такое получается. Думаю делать что-то типа метроидвании без боевки. Только на основе платформинга.
267 791165
>>91163
Кстати такие тени очень весело реализуются.
Это просто textureRect c modulate и оффсетом, на который рендерится viewport с уровнем. Дойдут руки - напишу шейдер
268 791167
>>91149

>Для более сложных игр нужны специализированные решения, которые не должны опираться на нодовую систему


Тыскозал? А я думаю наоборот. Чем сложнее игра, тем бессмысленнее отходить от нодовой системы. Если у тебя куча одноранговых объектов, это одно, а когда каждый уровень представляет собой иерархию статичных и динамичных объектов, тут уже проще не городить менеджер на куче исключений, а доверить этим объектам отвечать за себя самим.

>золотой молоток


Ну да, в официальных туторах хуйню же пишут.
https://docs.godotengine.org/en/stable/tutorials/io/saving_games.html

И вообще. Какой смысл брать движок, где всё делается нодами, и отказываться от нод? Мне так-то видится, что в саму философию Годо заложен принцип "каждая нода способна работать сама по себе".

>Вот я делаю большой открытый мир


А я делаю коридорный шутан. Естественно, сама архитектура наших проектов будет в корне отличаться.
269 791186
>>91163
Пока у тебя получается Celeste. Не как что-то плохое, да и в жанре платформера в принципе трудно что-то новое придумать.
270 791194
>>91167

>представляет собой иерархию статичных и динамичных объектов


Статичные должны загружаться автоматически при запуске tscn сцены, потому что они, по определению, никак не изменяются, поэтому сохранять их состояние не нужно.

Динамичные должны управляться соответствующим менеджером. Во-первых, не всегда динамичные объекты нужно сохранять, например, пешеходы в серии ГТА генерируются каждый раз заново и никуда не сохраняются. Во-вторых, менеджеру лучше известно, где и как должны располагаться его подчинённые, это не должно быть головной болью сейв-лоадера.

>Чем сложнее игра, тем бессмысленнее отходить от нодовой системы.


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

>в официальных туторах


Ну вот и делай как там, зачем что-то новое выдумывать...

>Какой смысл брать движок, где всё делается нодами, и отказываться от нод?


Смысл в том, чтобы использовать низкоуровневые возможности движка, не обременяя игру десятками тысяч бесполезных нод. В том же официальном руководстве есть отдельная статья, в которой признается тяжесть нод и предлагаются альтернативы. Алсо есть серверы и туториалы по их использованию - всё это в целях обойти систему нод.

>"каждая нода способна работать сама по себе"


Не каждая, лол. Взгляни хотя бы на PhysicsBody и CollisionShape - по отдельности они настолько бесполезны, что даже появляется специальное уведомление, если ты размещаешь их по отдельности. А если ты делаешь что-то сложное, например, персонажа, то у тебя внутри ноды персонажа будет куча других нод, которые не имеют смысла в твоей игре отдельно от ноды персонажа. Зачем тебе грузить эти ноды персонажа по отдельности, если ты можешь просто передать данные главной ноде персонажа, а она пусть сама решает, какие субноды ей нужно настроить, создать или удалить?

>коридорный шутан


В таком случае вообще не понимаю, чего ты паришься системой сохранений. Сделай чекпойнты в начале каждого уровня и всё, в сейве должны будут храниться только номер уровня, количество здоровья и патронов у игрока. Стоит ли делать что-то сложное уровня квиксейвов из халфы? Имхо, квиксейвы вообще портят удовольствие от прохождения коридорных шутеров, рука так и тянется загрузить игру после первого же попадания врага, а сейвить перед каждым поворотом...
270 791194
>>91167

>представляет собой иерархию статичных и динамичных объектов


Статичные должны загружаться автоматически при запуске tscn сцены, потому что они, по определению, никак не изменяются, поэтому сохранять их состояние не нужно.

Динамичные должны управляться соответствующим менеджером. Во-первых, не всегда динамичные объекты нужно сохранять, например, пешеходы в серии ГТА генерируются каждый раз заново и никуда не сохраняются. Во-вторых, менеджеру лучше известно, где и как должны располагаться его подчинённые, это не должно быть головной болью сейв-лоадера.

>Чем сложнее игра, тем бессмысленнее отходить от нодовой системы.


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

>в официальных туторах


Ну вот и делай как там, зачем что-то новое выдумывать...

>Какой смысл брать движок, где всё делается нодами, и отказываться от нод?


Смысл в том, чтобы использовать низкоуровневые возможности движка, не обременяя игру десятками тысяч бесполезных нод. В том же официальном руководстве есть отдельная статья, в которой признается тяжесть нод и предлагаются альтернативы. Алсо есть серверы и туториалы по их использованию - всё это в целях обойти систему нод.

>"каждая нода способна работать сама по себе"


Не каждая, лол. Взгляни хотя бы на PhysicsBody и CollisionShape - по отдельности они настолько бесполезны, что даже появляется специальное уведомление, если ты размещаешь их по отдельности. А если ты делаешь что-то сложное, например, персонажа, то у тебя внутри ноды персонажа будет куча других нод, которые не имеют смысла в твоей игре отдельно от ноды персонажа. Зачем тебе грузить эти ноды персонажа по отдельности, если ты можешь просто передать данные главной ноде персонажа, а она пусть сама решает, какие субноды ей нужно настроить, создать или удалить?

>коридорный шутан


В таком случае вообще не понимаю, чего ты паришься системой сохранений. Сделай чекпойнты в начале каждого уровня и всё, в сейве должны будут храниться только номер уровня, количество здоровья и патронов у игрока. Стоит ли делать что-то сложное уровня квиксейвов из халфы? Имхо, квиксейвы вообще портят удовольствие от прохождения коридорных шутеров, рука так и тянется загрузить игру после первого же попадания врага, а сейвить перед каждым поворотом...
271 791195
>>91167

>Какой смысл брать движок, где всё делается нодами, и отказываться от нод


Представил твоё лицо, когда ты рисуешь каждую травинку нодой.

>>91167

>коридорный шутан


Дерево узлов тоже не идеальная структура для хранения стен и статичной геометрии. Особенно такое, которое движок обходит каждый кадр.
272 791202
>>91194

>Динамичные должны управляться соответствующим менеджером.


Годо и так менеджерит всю физику. Не вижу смысла пилить ещё один менеджер для неё. Персонажи имеют всю нужную логику внутри себя. А что ещё там менеджерить-то? Двери?

>Тем временем даже в официальном реддите постят видосы "как я делаю игру на Годо без нод"


Ну молодцы, чо. Небось ещё и всю игровую логику на плюсах через нативскрипт пишут.
Я не понимаю смысла этой затеи, кроме "смотрите как могу". Кудрявое распрямить, прямое завить. Мощь Годо не в производительности, а в универсальности.

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


Ну кагбэ надо знать меру, не загоняться с

>каждую травинку нодой



>Не каждая, лол. Взгляни хотя бы на PhysicsBody и CollisionShape


Ну вот ты не понял суть изречения. И твои примеры как раз таки его подтверждают, а не опровергают.
Вполне можно было бы CollisionShape встроить в PhysicsBody в качестве экспортного ресурса. Но именно из-за концепции самостоятельности нод они разделены. Каждая из них самостоятельно выполняет свои функции. И внутри игрока будет куча нод по той же причине: каждая из них живёт своей жизнью, что в целом складывается в единый организм.

>Сделай чекпойнты в начале каждого уровня и всё


Фу блять. Фу нахуй. Б-гомерзкая консольная логика. Терпеть не могу игры без квиксейвов. Чувствую ужасный дискомфорт, когда не могу сохраниться перед заходом за очередной угол.
Если кого-то не устраивают квиксейвы, их можно отключить в настройках сложности.

>>91195

>Дерево узлов тоже не идеальная структура для хранения стен и статичной геометрии. Особенно такое, которое движок обходит каждый кадр.


Ну а что идеально, bsp-дерево? Так-то, конечно, для моих целей гораздо лучше подошёл бы DarkPlaces какой-нибудь. Но Годо всё-таки проще и удобнее.
273 791207
>>91145

> А может быть, я не знаю какой-то супер-ультимативный способ?


Хотел расписать свой способ, который предлагал в прошлых тредах. Но анон меня опередил:
>>91149

> Скажем, у тебя может быть менеджер уровня, который руководит расстановкой всех юнитов на карте - тебе не нужно сохранять позицию каждого юнита, достаточно только сохранить конкретные данные менеджера, которые он после загрузки использует для расстановки юнитов заново. Как он будет эти данные использовать, какие ноды создавать и в каком порядке - от системы сохранения и загрузки не зависит, от неё требуется только записать, а потом прочитать блок неких данных.



> Таким образом, для сохранения и загрузки игры мне достаточно сохранить и загрузить эти данные о мире, а всё остальное сработает автоматически, потому что никак не зависит от системы сохранения мира.



От себя добавлю два важных момента:
1. Такой подход позволяет изменять данные в тех локациях, которые не загружены в момент сохранения. Например, мы выполняем некий квест, в результате которого на определённой локации должен будет сработать определённый триггер. Казалось бы, почему бы нам просто при загрузке той локации не чекнуть, выполнен ли квест №100500? А если таких квестов 100500? Каждый чекать? Нет. Гораздо удобнее, когда игровой мир - это метаданные менеджера мира. И каждый квест производит изменения именно в метаданных. А уже локации при своей загрузке ничего не чекают, а читают метаданные и грузятся из них в правильной конфигурации.
2. Такой подход позволяет использовать любую организацию сохранения, хоть чекпоинты, хоть кастомсейвы, хоть быстрая загрузка из сохранённого в памяти состояния без работы с файлами вообще (полезно при боссфайтах). У тебя в памяти всегда висит полный набор метаданных мира. В любой момент ты можешь забэкапить его в переменную, или в файл сейва. Главное, организовать блокировки, если идёт сохранение, то дальнейшая запись в метаданные отвергается, на экране крутится значок сохранения в правом нижнем углу, ну и так далее.

>>91167

> в официальных туторах хуйню же пишут.


Да!
>>90722

> Прямо движок-специфичную инфу туда ебошишь, как предлагает документация в нарушение принципов SOLID? Нирикаминдую, если так

273 791207
>>91145

> А может быть, я не знаю какой-то супер-ультимативный способ?


Хотел расписать свой способ, который предлагал в прошлых тредах. Но анон меня опередил:
>>91149

> Скажем, у тебя может быть менеджер уровня, который руководит расстановкой всех юнитов на карте - тебе не нужно сохранять позицию каждого юнита, достаточно только сохранить конкретные данные менеджера, которые он после загрузки использует для расстановки юнитов заново. Как он будет эти данные использовать, какие ноды создавать и в каком порядке - от системы сохранения и загрузки не зависит, от неё требуется только записать, а потом прочитать блок неких данных.



> Таким образом, для сохранения и загрузки игры мне достаточно сохранить и загрузить эти данные о мире, а всё остальное сработает автоматически, потому что никак не зависит от системы сохранения мира.



От себя добавлю два важных момента:
1. Такой подход позволяет изменять данные в тех локациях, которые не загружены в момент сохранения. Например, мы выполняем некий квест, в результате которого на определённой локации должен будет сработать определённый триггер. Казалось бы, почему бы нам просто при загрузке той локации не чекнуть, выполнен ли квест №100500? А если таких квестов 100500? Каждый чекать? Нет. Гораздо удобнее, когда игровой мир - это метаданные менеджера мира. И каждый квест производит изменения именно в метаданных. А уже локации при своей загрузке ничего не чекают, а читают метаданные и грузятся из них в правильной конфигурации.
2. Такой подход позволяет использовать любую организацию сохранения, хоть чекпоинты, хоть кастомсейвы, хоть быстрая загрузка из сохранённого в памяти состояния без работы с файлами вообще (полезно при боссфайтах). У тебя в памяти всегда висит полный набор метаданных мира. В любой момент ты можешь забэкапить его в переменную, или в файл сейва. Главное, организовать блокировки, если идёт сохранение, то дальнейшая запись в метаданные отвергается, на экране крутится значок сохранения в правом нижнем углу, ну и так далее.

>>91167

> в официальных туторах хуйню же пишут.


Да!
>>90722

> Прямо движок-специфичную инфу туда ебошишь, как предлагает документация в нарушение принципов SOLID? Нирикаминдую, если так

274 791209
>>85715 (OP)
Как сделать шейдер похожего тумана?
https://youtu.be/v9zPkrxqpl0
Встроенный туман не работает, поэтому нужна альтернатива.
275 791214
>>91207
Вообще, сообразно своему опыту в общем кодинге могу предложить всем анонам начинать новый проект с написания (или копирования ранее написанного) модуля-конфигуратора, в котором методы напоминают функции работы с реестром шындовс: ключ, значение, дефолт-значение. Один инстанс конфигуратора настраиваете для работы с настройками самой игры, а второй - для работы с сохранениями. После чего в вашем дальнейшем коде совершенно исчезают т.н. "магические числа", каждое вручную введённое через геттер конфигуратора число, это уже не магическое число, а дефолт для настроек, который вы сможете поменять.
var gravity = Config.get_value("physics/gravity", 9.8) # Пример задания силы тяготения, которое всегда будет чекать конфиг на наличие сохранённого значения и подтянет новое, если найдёт.
Game.load_location(World.get_value("player/location", "whiterun")) # Пример загрузки локации, которая в отсутствие сейвов подстановится дефолтное, как в Скайриме, лол.
if quest.result = quest.results.bad_end: World.set_value("global/fractions/%s/relation_list/%s" % [quest.fraction, player.fraction], -100, true) # Пример модификации отношения фракции, указанной в метаданных квеста к фракции игрока при неудачном решении квеста. Необязательный логический параметр в конце по умолчанию ложь, но мы ставим его в правду, значит нам нужно прибавить минус 100 к имеющемуся значению. Если значения нет, конфигуратор создаст нулевое и вычтет из него.

Если кому интересно, могу поискать и выложить на пастебин готовый код такого конфигуратора (если найду в своих старых проектах, ушёл искать).
276 791224
>>91209
Делёз, жди беты 4.0, там туман полностью переработали:
https://github.com/godotengine/godot/pull/53353
В альфе скорее всего уже можешь оценить, как оно.
277 791235
>>91214

>начинать новый проект с написания


>или копирования ранее написанного


>если найду в своих старых проектах


Кек, у тебя кроме старых проектов ничего нет? Или ты сам себе противоречишь и не используешь эту систему в новых?

А по существу... не нравится мне такое, если где-то нужна константа - делай локальную константу, если вдруг понадобится её изменять извне - тогда и перенесёшь куда-то вовне. Та же гравитация в 99.9% проектах сойдёт стандартная, зачем её менять и проверять каждый кадр в каком-то глобальном хранилище?
278 791237
>>91235

> у тебя кроме старых проектов ничего нет?


Именно так. Джва года прокрастинации это нихуя не смешно.

> не нравится мне такое


Гравитация только в качестве примера. Что сохранять в файл - решаешь именно ты.

Поднял старые проекты. Там такой говнокод! Стыдно выкладывать. Если бы я делал это сегодня, сделал бы совершенно иначе.
279 791239
>>91237

>Поднял старые проекты. Там такой говнокод! Стыдно выкладывать. Если бы я делал это сегодня, сделал бы совершенно иначе.


Ну, это классека. Программист не программист если не совершенствуется, а совершенствуясь, свой старый код воспринимаешь отрицательно и стыдишься, начинаешь с нуля переписывать и т.д.
280 791251
>>91247 (Del)
Он уже на максималках хуярит, некуда улучшать
281 791303
>>91186

>Пока у тебя получается Celeste


Не скрываю, что вдохновлялся ей.
В Селесте крайнее хорошее управление, а код персонажа авторы выложили на гитхаб. Некоторые вещи я позаимствовал оттуда.

https://github.com/NoelFB/Celeste/tree/master/Source/Player
282 791309
>>91163

>эти шипы и пилы по всем стенам


Ух, как же я ненавижу такие игры. Кому нравится такое? Ты даже сам несколько раз сдох, прежде чем забрался на платформу.

>метроидвании без боевки


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

>>91303

>код персонажа авторы выложили на гитхаб


>5.4k строк if else if else if else if else if else if else...


Ого, чувствуется рука Мастера! Он тоже на C# шкодит.
283 791314
>>91309

>5.4k строк if else if else if else if else if else if else... Принесших миллионы долларов


Действительно мастер, не завидуй
284 791326
>>91314
Это отсылка на скандалы вокруг яндередева, лол.

>Принесших миллионы долларов


Продать любое говно можно, был бы хороший продавец. А у целесты графон и, наверное, сюжет очень крутые. За геймплей/код вообще редко игры любят (кроме песочниц). Часто можно слышать, как нахваливают графику и/или сюжет, реже нахваливают звук, но геймплей практически никогда не хвалят, только ругают, если что-то мешает наслаждаться графонием и/или сюжетом. Про код игроки вообще ничего не знают и не думают, пока он работает без падений, зависаний, глюков и переполнения памяти...
285 791340
>>91309

>туда-обратно несколько раз с ограниченными жизнями



Во-первых жанр не подразумевает ограничение по жизням.
Во-вторых обратно ходить тем же путем никто не заставляет. К тому же уровни в пресижн платформерах сложно спроектировать так, чтоб их было одинаково интересно проходить в обе стороне. Доходишь до определенного уровня - открывается шорткат.
286 791346
>>91309

>Слишком жестоко, заставлять прыгать по таким шипастым комнатам туда-обратно несколько раз с ограниченными жизнями.


Кстааати, платформер-кун, сделай для лютых хардкорщиков режим ограничения по жизням. Precise-платформер-метроидвания это же практически You Have To Win The Game (если не играл, настоятельно рекомендую ознакомиться, благо проходится вся игра за один вечер), а там как раз был такой режим.

>несколько раз сдох


Фишка в том, чтобы не воспринимать в этих играх жизни как жизни. Персонаж по сути бессмертен, так что он не сдох, а просто откинулся в начало уровня. Времени на это уходит минимум, акцента не делается, так что смерти не раздражают. Весь интерес - в преодолении сложностей, а преодолеваются они (при грамотном построении кривой сложности) за три-четыре попытки.
287 791348
>>91346

>сделай для лютых хардкорщиков режим ограничения по жизням



Можно, но стоит ли оно того? Тут вопрос психологии. Я считаю что лучше просто сделать счетчик смертей. Кто захочет - устроит сам себе челлендж.
288 791352
>>91348

>стоит ли оно того?


Обязательно стоит. Именно вопрос в психологии. Когда ты сам придумываешь для себя челлендж, тебе для этого не нужна игра. А если игра даёт тебе отдельный челлендж-режим, это уже совсем иначе воспринимается.
Счётчик смертей - хорошо. Ачивки "прошёл всю игру за 50, 10, 5, 1" смертей - ещё лучше. Плюс режим, где любая смерть завершает игру (и отдельная ачивка за прохождение в этом режиме), - совсем топчик. Режим с одной смертью и увеличенным количеством смертельных препятствий на уровне и ачивка на прохождение всего этого - вообще заебись.
Не заставляй игрока играть в воображаемую игру, пусть он играет в твою.
Ах да. Таймер прохождения для спидраннеров. Просто в конце уровня показать, сколько времени было на него потрачено. Кому надо - поймёт намёк и будет задрачивать до идеального времени.

Всё-таки современные платформеры это такой жанр, где не бывает мало хардкора. Кор-аудитория ради этого в них и играет.
чёрт, аж захотелось тоже платформер запилить.
death1.gif778 Кб, 460x314
289 791356
>>91346

>он не сдох


>акцента не делается


>пикрил.gif



>смерти не раздражают


Они не раздражают только если тебе не приходится по 10-20-50 раз проходить одну и ту же головоломку, пока необходимые нажатия клавиш не впечатаются в моторную память.

Впрочем, проехали, у меня просто с координацией движений и мелкой моторикой всё настолько плохо, что мне трудно попадать по клавишам и координировать движения двух рук, а одной рукой такое как правило не проходится и случайных нажатий не тех клавиш не терпит. Кто придумал биндить прыжок и стрельбу на z/x с управлением стрелочками? Требую wasd-платформеры, вот Террария норм с wasd играется, никто от этого "шутерного" управления в Террарии не умирал.

>>91352

>Таймер прохождения для спидраннеров. Просто в конце уровня показать, сколько времени было на него потрачено. Кому надо - поймёт намёк


Спидранерам сегодня важнее чтобы таймер отображался на экране всё время прохождения, а не только в конце уровня. Это раньше интернета не было, а сегодня спидранеры спидранят на видео и выкладывают в интернет, а какой спидран без таймера на экране? Так, я думаю, намного проще верифицировать рекордный спидран на сайте спидранов, там таймер на экране, вроде, обязательно нужен.
290 791358
>>91356

>мне трудно попадать по клавишам и координировать движения двух рук


С гейпада удобнее. Вообще, играть в платформеры на клаве - изврат и костыль. Китайский джой за 200р кардинально меняет взаимодействие с игрой.
С другой стороны, мы же про игры говорим. Если тебе не нравится, значит тебе не нравится.

>Требую wasd-платформеры


Двачаю. Или меню настроек клавиатуры, чтобы назначить любую клавишу на любое действие.

>Спидранерам сегодня важнее чтобы таймер отображался на экране всё время прохождения


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

>пик


Ну и сколько там времени проходит с момента смерти до рестарта? Всплывает какая-нибудь мрачная надпись под мрачную музыку? Выскакивает вопрос "рестарт/выйти"? Персонаж пляшет перед экраном, демонстрируя, как он ужасно умер?
Просто если сравнивать современные платформеры и игры из 90х, в современных акцента на смертях совсем не делается. Наткнулся на препятствие, быстренько умер, сразу ожил у чекпоинта.
uitween3.gif3,3 Мб, 613x741
291 791412
>>91163
Решил немного отвлечься и заняться менюшками. Пока что остановился на чем-то эдаком. Думаю, весь интерфейс будет в FHD, а сам геймплей пикселявым. Благо это не так уж и сложно сделать и все выглядит весьма аккуратно, если наложить одно на другое. Опять же какой-то худ во время геймплея я не хочу показывать игроку. Максимум - появляющийся на пару секунд после гибели счетчик смертей или счетчик бонусок после подъема бонуски.

inb4: Да, шрифт из губки боба, его я буду менять
292 791413
>>91412
Это кстати стандартные годотовские кнопки в VBoxКонтейнере
293 791425
>>91412
Норм. Я бы от себя предложил сделать иконки отдельно шевеляшимися.
294 791445
>>91412
Это шрифт или нарисованные надписи? Если второе, то с локализацией могут быть проблемы. Я из-за этого для своей игры не стал шрифт рисовать, взял готовый. Кириллица и латиница норм, а вот всякие ивриты или китайские иероглифы - там можно по незнанию накосячить.
1644949469511.png44 Кб, 898x723
295 791463
>>91445

> с локализацией могут быть проблемы


Думай о локализации на стадии проектирования и предпродакшена. А в движке есть механизмы как локализованные пикчи из нужных папочек подставлять.
296 791478
>>91445

>Это шрифт или нарисованные надписи?


Шрифт
297 791479
>>91463

>А в движке есть механизмы как локализованные пикчи из нужных папочек подставлять


Чел, я в курсе. А рисовать я тебе как буду на китайском? А если палочку не в том месте поставлю, и вместо "новая игра" получится "ослиная жопа"? Можно отдать перевод на аутсорс, но одно дело только перевести текст, совсем другое перевести и нарисовать переведённое.
298 791486
>>91163
Пишу кастомную камеру и менеджер уровней.
Камера поддерживает комнаты в один экран и комнаты с горизонтальным и/или вертикальным скроллом камеры

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

Как только заходишь в новую комнату, все предыдущие выгружаются из общей сцены и подгружаются все пограничные комнаты с новой. Это даст игроку бесшовный геймплей и позволит разгрузить физ. движок, так как в комнатах может быть много двигающихся обьектов
299 791489
>>91486
Чего свой тред не заводишь? А лучше твиттер, реддит или ещё в каких соцсетках страницу. Пропадает материал для продвижения. Ты ежедневно постишь отчёты о разработке, а это же отличный способ уже сейчас начать продвигать игру. Только постить нужно на платформах с системой рекомендаций, а не в медленном треде медленного раздела двача.
Platoformer1 (DEBUG) 2022-02-16 11-46-47.mp429,1 Мб, mp4,
1920x1080, 0:23
300 791491
>>91486
Со сглаживанием.

>>91489
Да я же для души делаю. Планирую ютуб завести и пилить туда девлоги с уклоном в технические аспекты и элементами обучалок.

А вообще ты прав. Когда нет поддержки со стороны аудитории и ответственности перед ней гораздо проще забить на проект
301 791496
Уже который год ломаю голову над совмещением стилизованного модульного ландшафта с разницей высот так, чтобы машинки могли забираться на ступеньки не как в майнкрафте - наконец-то к чему-то начинаю приходить, благодаря пикрилу. Всего-то и нужно было, что оставить выступы там, где нет дорог, без попытки сгладить всё на свете, ведь там всё равно никто ездить не будет, следовательно, и сглаживание там не нужно...

Высота выступов здесь примерно 6 метров, но персонаж всё равно может пешком забраться, из-за того, что сидит на рейкасте( На трёхметровый выступ вообще залетает без замедления...

Теперь осталось понять, как соединять несколько мешей в один, если один из мешей нужно развернуть на 90/180/270 градусов. Вручную умножать каждую вершину на матрицу поворота? Не делать же мне по 4 отдельных меша на каждый угол поворота, лол. Угол поворота я уже давно умею вычислять (на старых скриншотах, если кто-то помнит, тайлы дорог правильно ориентировались).

Эх, даже такую примитивную игру с тайлами так тяжело делать, не представляю, насколько сложнее делать реалистичную игру... А ведь раньше были фантазии чтоб всё это с онлайном 1000+ человек и ещё куча всяких сложных возможностей... А сейчас главная цель - перебороть депру и допилить прототип до минимально играбельного состояния, чтобы проект сам генерировал мотивацию доделать себя, давал мотивацию жить...
302 791497
>>91491

>Планирую ютуб завести


Не планируй, делай. Я же первый подпишусь.
Но ютуб это трудозатратно. Я не раз и не два пробовал пилить видосы по разным темам, всегда упирался в то, что на основную деятельность переставало хватать времени. Поэтому, кстати, так и взлетели в своё время сначала Твиттер, потом Тикток: быстрее пилить контент, значит проще систематически постить.
Ну ты в любом случае держи в курсе.
303 791498
>>91496

>Теперь осталось понять, как соединять несколько мешей в один


https://docs.godotengine.org/ru/stable/tutorials/3d/using_gridmaps.html

Конечно меши в один не соединяются. По сути это аналог тайлмапа для 3Д
304 791502
>>91501 (Del)
Ни разу не работал в геймдеве с 3д. Вообще попробовать хочется
kysjxp4l.gif1,4 Мб, 400x283
305 791503
>>91412

>Думаю, весь интерфейс будет в FHD, а сам геймплей пикселявым.


У меня, как игрока/пользователя, всегда разрыв шаблона от такого нелогичного решения. Любая игра должна иметь свой стиль, и этот стиль должен быть консистентным по всей игре. Решил делать "типа ретро пикселяч" - делай его не только в геймплее, но и в менюшках. Иначе разрыв шаблона, когда игрок видит в главном меню векторную красоту времён веб 2.0, а после начала игры видит ультра минималистичный пикселяч 8х8 пикселей, который нужно разглядывать как на пикрил.gif. Зачем обламывать игрока?

>>91445

>Кириллица и латиница норм, а вот всякие ивриты или китайские иероглифы - там можно по незнанию накосячить.


Во-первых, зачем тебе выходить со своей по определению никому не нужной индюшатиной (без обид, нужно быть реалистом) на китайский и индусский рынок?

Во-вторых, локализовать игру на какой-то язык - не означает выйти на соответствующий рынок. Тебе ещё реклама нужна и фанбаза в соответствующем регионе. А фанбаза требует поддержки. Сможешь ты отвечать на вопросы китайцев и индусов так, чтобы они тебя понимали? Инглиш они знают в среднем намного хуже, чем мы. Или у тебя есть бюджет и на рекламу, и на коммьюнити-менеджеров для каждого региона? Ну с таким-то бюджетом вообще не вижу проблем локализовать картинки.

В-третьих, всем насрать на эту стилизацию шрифтов. Майнкрафт долгие годы имел ублюдочную кириллицу, которую приходилось исправлять фанатским модом - то есть перевод на русский был официальный, а вот официальный шрифт для кириллицы был говно, при том что латиница была нормальной. Что уж говорить о всяких иероглифах и прочих закорючках, которые хрен впишешь в 8х8 пикселей. Смогли исправить, похоже, только после покупки моджанга майкрософтом, лол, сами бы они никогда не додумались.

В-четвёртых, у таких изолированных регионов, как китайцы, японцы, индусы и прочих, своя локальная культура и интересы. Наши СНГшные и тем более западные ценности им чужды и неинтересны. Ты не можешь одновременно вылизать геймплей и сюжет для запада и востока, чтобы он одновременно хорошо зашёл и тем, и другим. А поскольку в восточных культурах ты с большой вероятностью ничего не смыслишь (ведь твой опыт ограничен просмотром аниме и, максимум, какого-нибудь канала "русский эмигрант в такой-то стране"), то можешь адаптировать игру только для СНГ и запада.

Короче, хватит мечтать о миллиардах индусов и китайцев, стачивающих клавиши в твоей индюшке на 1.5 часа геймплея, это бессмысленная трата времени и средств. Лучше сделать хорошую игру на русском и английском языках, чем размазывать свои ресурсы на два десятка никому не нужных локализаций. Большинство инди так и делают и никаких проблем с этим не имеют (потому что не могут даже так раскрутиться, куда им лишние локализации, лол).

>>91479

>А рисовать я тебе как буду на китайском?


Здесь всё очень просто. Стилизованные надписи только латиницей и кириллицей, а всё остальное - стандартным международным шрифтом с открытой лицензией. Ты думаешь, кто-нибудь заметит разницу? Кого-нибудь будет эта разница волновать? См. пример выше с майнкрафтом - они даже кириллицу не могли адаптировать, лол, хотя кириллица очень похожа на латиницу и часть букв можно тупо скопипастить, но нет, хрен вам, вот тонюсенькие ублюдочные юникодовскик буковки вместо нормального пиксельного шрифта. И всё норм было, кто хотел - ставил мод, остальные терпели и просили добавки.

Так что вопрос не в том, как сделать локализацию, а зачем её делать. Инди в 99.9(9)% локализация на десятки языков не нужна, ведь он даже в родном регионе не осилит фанбазу набрать, лол.

>>91486
Тебя самого не напрягает гифки в 20 МБ делать? Что мешает конвертировать в webm? Будет меньше весить и появится возможность перемотать интересный момент. Гифки имеют смысл только если что-то за 1-2 секунды повторяется.

Алсо, это вкусовщина, но лично меня дико напрягают игры, в которых нужно спрыгивать вниз в "трубу", чтобы оказаться в нижней комнате. Во-первых, нет никакой гарантии что там внизу другая комната, а не бесконечная пропасть. Во-вторых, нет никакой гарантии что в этой нижней комнате безопасный пол, а не куча пил и шипов. Даже если число жизней бесконечно и ты возраждаешься на предыдущем безопасном участке (т.е. до прыжка), всё равно прыгать в неизвестность стрёмно. Ну это так... субъективно. У меня из опыта платформеров больше всего часов в Террарии, там просто десятки способов избежать смерти от падения и всё равно регулярно дохнешь, неприятно.

>>91489

>твиттер


>уже сейчас начать продвигать игру


Видел уже наверное десятки твиттеров разработчиков игр, где они регулярно постят прогресс с кучей тегов, а получают 0 ретвитов и 1-2 лайка. Офигеть продвижение, конечно. При том что у них там не микропикселяч какой-то, а вполне годная стильная 3Д графика. Короче, не всё так просто... Алсо твиттер последнее время стал закручивать гайки, теперь без авторизации невозможно нормально листать посты, сраное окно "войдите, чтобы читать @юзернейм" всплывает после 3-4 постов.

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

>>91491

>Когда нет поддержки со стороны аудитории и ответственности перед ней гораздо проще забить на проект.


Согласен на все 100%, даже если "делаешь для себя", мотивация как-то падает без поддержки. Но это индивидуально, уверен, есть люди, которые многие годы ежедневно что-то делают тайно от всех и совершенно не нуждаются в поддержке со стороны. Типа отшельники цифрового века, не нуждаются в этой нашей всемирной электронной деревне. Хотелось бы быть таким отшельником...
kysjxp4l.gif1,4 Мб, 400x283
305 791503
>>91412

>Думаю, весь интерфейс будет в FHD, а сам геймплей пикселявым.


У меня, как игрока/пользователя, всегда разрыв шаблона от такого нелогичного решения. Любая игра должна иметь свой стиль, и этот стиль должен быть консистентным по всей игре. Решил делать "типа ретро пикселяч" - делай его не только в геймплее, но и в менюшках. Иначе разрыв шаблона, когда игрок видит в главном меню векторную красоту времён веб 2.0, а после начала игры видит ультра минималистичный пикселяч 8х8 пикселей, который нужно разглядывать как на пикрил.gif. Зачем обламывать игрока?

>>91445

>Кириллица и латиница норм, а вот всякие ивриты или китайские иероглифы - там можно по незнанию накосячить.


Во-первых, зачем тебе выходить со своей по определению никому не нужной индюшатиной (без обид, нужно быть реалистом) на китайский и индусский рынок?

Во-вторых, локализовать игру на какой-то язык - не означает выйти на соответствующий рынок. Тебе ещё реклама нужна и фанбаза в соответствующем регионе. А фанбаза требует поддержки. Сможешь ты отвечать на вопросы китайцев и индусов так, чтобы они тебя понимали? Инглиш они знают в среднем намного хуже, чем мы. Или у тебя есть бюджет и на рекламу, и на коммьюнити-менеджеров для каждого региона? Ну с таким-то бюджетом вообще не вижу проблем локализовать картинки.

В-третьих, всем насрать на эту стилизацию шрифтов. Майнкрафт долгие годы имел ублюдочную кириллицу, которую приходилось исправлять фанатским модом - то есть перевод на русский был официальный, а вот официальный шрифт для кириллицы был говно, при том что латиница была нормальной. Что уж говорить о всяких иероглифах и прочих закорючках, которые хрен впишешь в 8х8 пикселей. Смогли исправить, похоже, только после покупки моджанга майкрософтом, лол, сами бы они никогда не додумались.

В-четвёртых, у таких изолированных регионов, как китайцы, японцы, индусы и прочих, своя локальная культура и интересы. Наши СНГшные и тем более западные ценности им чужды и неинтересны. Ты не можешь одновременно вылизать геймплей и сюжет для запада и востока, чтобы он одновременно хорошо зашёл и тем, и другим. А поскольку в восточных культурах ты с большой вероятностью ничего не смыслишь (ведь твой опыт ограничен просмотром аниме и, максимум, какого-нибудь канала "русский эмигрант в такой-то стране"), то можешь адаптировать игру только для СНГ и запада.

Короче, хватит мечтать о миллиардах индусов и китайцев, стачивающих клавиши в твоей индюшке на 1.5 часа геймплея, это бессмысленная трата времени и средств. Лучше сделать хорошую игру на русском и английском языках, чем размазывать свои ресурсы на два десятка никому не нужных локализаций. Большинство инди так и делают и никаких проблем с этим не имеют (потому что не могут даже так раскрутиться, куда им лишние локализации, лол).

>>91479

>А рисовать я тебе как буду на китайском?


Здесь всё очень просто. Стилизованные надписи только латиницей и кириллицей, а всё остальное - стандартным международным шрифтом с открытой лицензией. Ты думаешь, кто-нибудь заметит разницу? Кого-нибудь будет эта разница волновать? См. пример выше с майнкрафтом - они даже кириллицу не могли адаптировать, лол, хотя кириллица очень похожа на латиницу и часть букв можно тупо скопипастить, но нет, хрен вам, вот тонюсенькие ублюдочные юникодовскик буковки вместо нормального пиксельного шрифта. И всё норм было, кто хотел - ставил мод, остальные терпели и просили добавки.

Так что вопрос не в том, как сделать локализацию, а зачем её делать. Инди в 99.9(9)% локализация на десятки языков не нужна, ведь он даже в родном регионе не осилит фанбазу набрать, лол.

>>91486
Тебя самого не напрягает гифки в 20 МБ делать? Что мешает конвертировать в webm? Будет меньше весить и появится возможность перемотать интересный момент. Гифки имеют смысл только если что-то за 1-2 секунды повторяется.

Алсо, это вкусовщина, но лично меня дико напрягают игры, в которых нужно спрыгивать вниз в "трубу", чтобы оказаться в нижней комнате. Во-первых, нет никакой гарантии что там внизу другая комната, а не бесконечная пропасть. Во-вторых, нет никакой гарантии что в этой нижней комнате безопасный пол, а не куча пил и шипов. Даже если число жизней бесконечно и ты возраждаешься на предыдущем безопасном участке (т.е. до прыжка), всё равно прыгать в неизвестность стрёмно. Ну это так... субъективно. У меня из опыта платформеров больше всего часов в Террарии, там просто десятки способов избежать смерти от падения и всё равно регулярно дохнешь, неприятно.

>>91489

>твиттер


>уже сейчас начать продвигать игру


Видел уже наверное десятки твиттеров разработчиков игр, где они регулярно постят прогресс с кучей тегов, а получают 0 ретвитов и 1-2 лайка. Офигеть продвижение, конечно. При том что у них там не микропикселяч какой-то, а вполне годная стильная 3Д графика. Короче, не всё так просто... Алсо твиттер последнее время стал закручивать гайки, теперь без авторизации невозможно нормально листать посты, сраное окно "войдите, чтобы читать @юзернейм" всплывает после 3-4 постов.

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

>>91491

>Когда нет поддержки со стороны аудитории и ответственности перед ней гораздо проще забить на проект.


Согласен на все 100%, даже если "делаешь для себя", мотивация как-то падает без поддержки. Но это индивидуально, уверен, есть люди, которые многие годы ежедневно что-то делают тайно от всех и совершенно не нуждаются в поддержке со стороны. Типа отшельники цифрового века, не нуждаются в этой нашей всемирной электронной деревне. Хотелось бы быть таким отшельником...
306 791512
>>91503

>Во-первых, зачем тебе выходить со своей по определению никому не нужной индюшатиной (без обид, нужно быть реалистом) на китайский и индусский рынок?


Действительно, зачем выходить на самый большой рынок в мире?
(я уже прочитал весь пост и увидел подвешенное ружьё, это ответ вне контекста)

Вообще, ты всё правильно говоришь. Просто моя мысль в том, что если можно какую-то проблему решить на стадии проектирования, это надо сделать.

>В-третьих, Майнкрафт


Вот уж не пример ни разу. Майн хорош геймплеем и всё. Даже среди кубов есть куча игр, которые его превосходят по всем показателям, но так уж случилось, что он выстрелил первым. Это не повод приводить МС в пример чего бы то ни было, кроме гейм-дизайна.

>В-четвёртых, у таких изолированных регионов, как китайцы, японцы, индусы и прочих, своя локальная культура и интересы


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

>Видел уже наверное десятки твиттеров разработчиков игр, где они регулярно постят прогресс с кучей тегов, а получают 0 ретвитов и 1-2 лайка


Тащемта у твиттера своя специфика. Там лучше заходят всякие провокации и срачи, чем годнота.

>"войдите, чтобы читать @юзернейм"


Сук горит, когда сайты так делают. Инстаграмом из-за этого (и некоторого другого подобного) говна не пользуюсь.
307 791516
>>91500 (Del)

>А в чем трудность?


Я же говорю, трудность в том, чтобы разворачивать тайлы на 90/180/270 градусов. Если тайлы - отдельные ноды, то достаточно развернуть их через rotation. Если тайлы - плоские квадраты, то можно ограничиться разворотом UV координат, без перерасчёта вершин. Но если тайлы имеют сложную геометрию и их нужно сшить в один меш, то придётся каждую вершину вручную вертеть...

>Там же куча функций для поворота нод.


Это если ноды отдельные. Я хочу зашивать геометрию чанка/тайла в один MeshInstance, чтобы сократить количество нод и число дроуколлов (т.к. батчинга в 3.х нет). Даже когда появится батчинг, лучше избегать лишних нод. Также, когда весь чанк (несколько тайлов) - один меш, можно сделать один общий Shape с помощью Mesh.create_trimesh_shape(), что сокращает количество CollisionShape (и, по идее, запросы к физическому движку).

Проще говоря, выгоднее иметь такую структуру нод:
- Chunks: StaticBody
- - Chunk1234: CollisionShape
- - - Mesh1234: MeshInstance
Чем наворачивать тысячи мешей и отдельных шейпов.
Также это проще переделать на серверы, если понадобится.

>Ну на твоем лоуполи это в общем то не страшно


Это только плейсхолдеры, я не определился с графикой. Прежде чем делать что-то детализированное, нужно определиться с базовой геометрией, которую можно и нужно из кубов лепить.

>>91498

>GridMap


Я пробовал его, но с ним куча вопросов возникает.
1. Каждый блок рисуется независимо/батчинга ведь нет?
2. Каждый блок имеет свой StaticBody + CollisionShape?
3. К блоку GridMap нельзя привязать другие ноды? У меня, например, деревья и дома вставляются в ноду блока/чанка (CollisionShape), что позволяет отображать и скрывать их все вместе.
4. Непонятно как делать чанки: делать несколько GridMap или загонять новые блоки в один глобальный GridMap?
5. Что на счёт вложенного подразделения? У меня только базовые тайлы карты 24х24 метра, но в некоторых местах планируется подразделение на сетки 6х6 метров (парк) и кубы 3х3х3 метра (здания из подобных "кубических" модулей, 1 модуль = 1 этаж). Получается, на каждый такой подразделённый блок создавать свою GridMap? Я думал сшивать всё в один MeshInstance, чтобы сократить число нод, дроуколлов и отдельных коллиженшейпов.

Ещё GridMap мне не нравится тем, что реализация скрыта где-то в недрах движка на C++ и в документации по сути кроме API ничего нет, как оно там под капотом работает и как его могут изменить в будущих версиях движка (систему навигации вот полностью переделали, следовательно все старые проекты на старой навигации при переходе на новую версию развалятся). Если опираться только на базовые меши и шейпы, у тебя в руках вся логика, и сломаться из-за движка практически нечему, можно даже на другой движок безболезненно перекатиться или переписать скрипты на другой язык (GDNative). Короче, не хочу впадать в зависимость от какой-то непопулярной фичи с непонятным предназначением (майнкрафт на базе GridMap не сделать - будет жутко тормозить, ну и зачем она тогда нужна?).
307 791516
>>91500 (Del)

>А в чем трудность?


Я же говорю, трудность в том, чтобы разворачивать тайлы на 90/180/270 градусов. Если тайлы - отдельные ноды, то достаточно развернуть их через rotation. Если тайлы - плоские квадраты, то можно ограничиться разворотом UV координат, без перерасчёта вершин. Но если тайлы имеют сложную геометрию и их нужно сшить в один меш, то придётся каждую вершину вручную вертеть...

>Там же куча функций для поворота нод.


Это если ноды отдельные. Я хочу зашивать геометрию чанка/тайла в один MeshInstance, чтобы сократить количество нод и число дроуколлов (т.к. батчинга в 3.х нет). Даже когда появится батчинг, лучше избегать лишних нод. Также, когда весь чанк (несколько тайлов) - один меш, можно сделать один общий Shape с помощью Mesh.create_trimesh_shape(), что сокращает количество CollisionShape (и, по идее, запросы к физическому движку).

Проще говоря, выгоднее иметь такую структуру нод:
- Chunks: StaticBody
- - Chunk1234: CollisionShape
- - - Mesh1234: MeshInstance
Чем наворачивать тысячи мешей и отдельных шейпов.
Также это проще переделать на серверы, если понадобится.

>Ну на твоем лоуполи это в общем то не страшно


Это только плейсхолдеры, я не определился с графикой. Прежде чем делать что-то детализированное, нужно определиться с базовой геометрией, которую можно и нужно из кубов лепить.

>>91498

>GridMap


Я пробовал его, но с ним куча вопросов возникает.
1. Каждый блок рисуется независимо/батчинга ведь нет?
2. Каждый блок имеет свой StaticBody + CollisionShape?
3. К блоку GridMap нельзя привязать другие ноды? У меня, например, деревья и дома вставляются в ноду блока/чанка (CollisionShape), что позволяет отображать и скрывать их все вместе.
4. Непонятно как делать чанки: делать несколько GridMap или загонять новые блоки в один глобальный GridMap?
5. Что на счёт вложенного подразделения? У меня только базовые тайлы карты 24х24 метра, но в некоторых местах планируется подразделение на сетки 6х6 метров (парк) и кубы 3х3х3 метра (здания из подобных "кубических" модулей, 1 модуль = 1 этаж). Получается, на каждый такой подразделённый блок создавать свою GridMap? Я думал сшивать всё в один MeshInstance, чтобы сократить число нод, дроуколлов и отдельных коллиженшейпов.

Ещё GridMap мне не нравится тем, что реализация скрыта где-то в недрах движка на C++ и в документации по сути кроме API ничего нет, как оно там под капотом работает и как его могут изменить в будущих версиях движка (систему навигации вот полностью переделали, следовательно все старые проекты на старой навигации при переходе на новую версию развалятся). Если опираться только на базовые меши и шейпы, у тебя в руках вся логика, и сломаться из-за движка практически нечему, можно даже на другой движок безболезненно перекатиться или переписать скрипты на другой язык (GDNative). Короче, не хочу впадать в зависимость от какой-то непопулярной фичи с непонятным предназначением (майнкрафт на базе GridMap не сделать - будет жутко тормозить, ну и зачем она тогда нужна?).
308 791519
>>91498

>Конечно меши в один не соединяются.


>Internally, a GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells.


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

>По сути это аналог тайлмапа для 3Д


У тайлмапа вроде как есть батчинг...

В общем, ладно, просто протестирую и посмотрю, что получится. Я нашёл в API функции разворота отдельных мешей, плюс как я понял это всё на низком уровне, в обход дерева сцены работает, что должно быть лучше, чем если я буду на нодах и гдскрипт делать...

>>91516

>вложенное подразделение


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

Было бы интересно ещё и деревья как блоки GridMap размещать, а не независимо, чтобы не париться на счёт перекрытий (когда объекты наезжают друг на друга), но сами деревья (стволы и листья) я собирался процедурно генерировать... Ладно, это пока не важно.
309 791522
>>91520 (Del)

>SurfaceTool


ArrayMesh же. SurfaceTool для детей))

>брать .x вместо .y и -.y вместо .x, условно


Ааааа... Теперь дошло. Чёт я вообще не подумал об этом, хотел писать свои функции с матрицами поворота. Спасибо.

>какие ограничения дает один большой меш на тени и источники света?


Какие же? Я пока знаю только что каждый источник света умножает число дроуколлов на 2, следовательно, чем меньше отдельных мешей, тем больше источников света можно сделать. Если у тебя один меш и 2 источника света, это 3 дроуколла, а если 10 мешей с теми же 2 источниками света - это 30 дроуколлов. Ну а с тенями всё проще, они у меня почему-то на очень короткой дистанции рендерятся, чуть камеру отдаляешь и теней уже нет, лол.

>фары


Разве фары в играх являются настоящим источником света?

>Я вот читал, что большие коллижншейпы плохо


Я читал, что плохо не только большие, но мелкие. Главная проблема не в расчётах, а в том, что на стыках коллиженшейпов происходит какой-то баг, из-за которого объекты дёргаются. Т.е. нужно соблюдать баланс между слишком большими и слишком мелкими шейпами. Что же касается производительности, у меня около 1000 отдельных шейпов перегружают физический движок, т.е. нужно делить шейпы на несколько статикбоди или объединять мелкие шейпы в один большой.

>А ты уже уперся в дровколлы?


Ты тут недавно что ли? Я уже постил скриншоты где у меня больше 10 тысяч дроуколлов на визуально простой карте. Даже просто вывод голых плиток занимал 500 дроуколлов на небольшой территории без источника света (лол), пока я не начал объединять их в один меш на каждом чанке.

>вариант на мультимешинстансах


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

Ладно, я уже решил сделать отдельный тест на гридмапах, много переделывать придётся, но это лучше, чем сидеть сложа руки и ломать голову над тем, как загонять тайлы в велосипедные чанки...
309 791522
>>91520 (Del)

>SurfaceTool


ArrayMesh же. SurfaceTool для детей))

>брать .x вместо .y и -.y вместо .x, условно


Ааааа... Теперь дошло. Чёт я вообще не подумал об этом, хотел писать свои функции с матрицами поворота. Спасибо.

>какие ограничения дает один большой меш на тени и источники света?


Какие же? Я пока знаю только что каждый источник света умножает число дроуколлов на 2, следовательно, чем меньше отдельных мешей, тем больше источников света можно сделать. Если у тебя один меш и 2 источника света, это 3 дроуколла, а если 10 мешей с теми же 2 источниками света - это 30 дроуколлов. Ну а с тенями всё проще, они у меня почему-то на очень короткой дистанции рендерятся, чуть камеру отдаляешь и теней уже нет, лол.

>фары


Разве фары в играх являются настоящим источником света?

>Я вот читал, что большие коллижншейпы плохо


Я читал, что плохо не только большие, но мелкие. Главная проблема не в расчётах, а в том, что на стыках коллиженшейпов происходит какой-то баг, из-за которого объекты дёргаются. Т.е. нужно соблюдать баланс между слишком большими и слишком мелкими шейпами. Что же касается производительности, у меня около 1000 отдельных шейпов перегружают физический движок, т.е. нужно делить шейпы на несколько статикбоди или объединять мелкие шейпы в один большой.

>А ты уже уперся в дровколлы?


Ты тут недавно что ли? Я уже постил скриншоты где у меня больше 10 тысяч дроуколлов на визуально простой карте. Даже просто вывод голых плиток занимал 500 дроуколлов на небольшой территории без источника света (лол), пока я не начал объединять их в один меш на каждом чанке.

>вариант на мультимешинстансах


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

Ладно, я уже решил сделать отдельный тест на гридмапах, много переделывать придётся, но это лучше, чем сидеть сложа руки и ломать голову над тем, как загонять тайлы в велосипедные чанки...
310 791552
>>91479

> А рисовать я тебе как буду на китайском?


Никак.
Ты сделаешь на русском и английском. Можешь скринить.
1645021570885.png14 Кб, 606x135
311 791555
>>91516

> (т.к. батчинга в 3.х нет)


Где об этом почитать?
312 791576
MeshLibrary: 1 юзабилити из 10 мешей
За джва года так и не пофиксили баг(

>>91534 (Del)

>Лимит источников на весь меш


Откуда этот лимит-то, если каждый источник сцены рендерит всю сцену с нуля сам по себе? Или этот лимит на OpenGL шейдинг? Про лимит в 8 источников света у OpenGL я знаю, но тени OpenGL вообще рендерить не умеет.

>костыли в контроллере


Сомневаюсь, что можно закостылить этот баг на стыках. Только сами стыки прятать куда-то. Но в любом случае он проявляется редко и на низкой скорости в глаза не бросается, так что пофиг пока. А в 4.0 наверняка уже поправили (некоторые фиксы до сих пор не портированы на 3.х).

>>91555

>Где об этом почитать?


Что ты читать собрался? В руководстве очень мутно написано про батчинг, нет чёткого описания, что есть в движке, а чего нет. Пишут, что для 3D батчинг нужен, но такое ощущение, что предлагают сделать его вручную. Типа перечисляют плюсы и минусы батчинга, лол, как будто и без этого не понятно, что он нужен.

>OpenGL ES Batching: ON


Это только 2D батчинг - для нод, являющихся потомками Node2D и Control. В то же время 3D, т.е. потомки Spatial, в ветке 3.х пока что не имеет батчинга - он реализован только в альфе 4.0.

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

Вот тебе пруфы:
2) 1000 статичных кубов на 3.4.2 - 2000 дроуколлов.
3) 1000 ригидбоди кубов на альфе 4.0 - 2 дроуколла.
Также почитай предыдущий тред, ссылка в шапке. Там я ближе к концу треда обсуждал тему дроуколлов (так и ищи: ctrl+f, "дроук"). У меня один лес из одинаковых деревьев давал больше 5 тысяч дроуколлов, хотя выглядел совсем не так плотно, как тысяча кубов, на экране этих пары тысяч деревьев вообще могло не быть.

Да, кстати, использование визуального сервера не помогает против дроуколлов: ноды не будут использоваться, но все кубы будут рендериться по отдельности. Именно поэтому большое количество уникальных объектов лучше сшивать в один меш, по крайней мере пока не перекатимся на 4.0. Одинаковые меши можно выводить через мультимеш, да, но в реальной сцене большинство объектов будут уникальны, даже если выглядят примитивно.
312 791576
MeshLibrary: 1 юзабилити из 10 мешей
За джва года так и не пофиксили баг(

>>91534 (Del)

>Лимит источников на весь меш


Откуда этот лимит-то, если каждый источник сцены рендерит всю сцену с нуля сам по себе? Или этот лимит на OpenGL шейдинг? Про лимит в 8 источников света у OpenGL я знаю, но тени OpenGL вообще рендерить не умеет.

>костыли в контроллере


Сомневаюсь, что можно закостылить этот баг на стыках. Только сами стыки прятать куда-то. Но в любом случае он проявляется редко и на низкой скорости в глаза не бросается, так что пофиг пока. А в 4.0 наверняка уже поправили (некоторые фиксы до сих пор не портированы на 3.х).

>>91555

>Где об этом почитать?


Что ты читать собрался? В руководстве очень мутно написано про батчинг, нет чёткого описания, что есть в движке, а чего нет. Пишут, что для 3D батчинг нужен, но такое ощущение, что предлагают сделать его вручную. Типа перечисляют плюсы и минусы батчинга, лол, как будто и без этого не понятно, что он нужен.

>OpenGL ES Batching: ON


Это только 2D батчинг - для нод, являющихся потомками Node2D и Control. В то же время 3D, т.е. потомки Spatial, в ветке 3.х пока что не имеет батчинга - он реализован только в альфе 4.0.

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

Вот тебе пруфы:
2) 1000 статичных кубов на 3.4.2 - 2000 дроуколлов.
3) 1000 ригидбоди кубов на альфе 4.0 - 2 дроуколла.
Также почитай предыдущий тред, ссылка в шапке. Там я ближе к концу треда обсуждал тему дроуколлов (так и ищи: ctrl+f, "дроук"). У меня один лес из одинаковых деревьев давал больше 5 тысяч дроуколлов, хотя выглядел совсем не так плотно, как тысяча кубов, на экране этих пары тысяч деревьев вообще могло не быть.

Да, кстати, использование визуального сервера не помогает против дроуколлов: ноды не будут использоваться, но все кубы будут рендериться по отдельности. Именно поэтому большое количество уникальных объектов лучше сшивать в один меш, по крайней мере пока не перекатимся на 4.0. Одинаковые меши можно выводить через мультимеш, да, но в реальной сцене большинство объектов будут уникальны, даже если выглядят примитивно.
313 791759
Хренасе на какую багу я наткнулся

>export(Array, int) var arr1 = [0,0,0,0,0,0,0,0,0]


>export(Array, int) var arr2 = [0,0,0,0,0,0,0,0,0]


>.....


>arr2[3] = 16


>print(arr1[3])


>#16


Если при инициализации массивы будут чуть различаться, они не слинкуются. Если объявлять просто как переменные, без экспорта, тоже всё нормально. А вот в таком виде работают как ссылка на одну и ту же область в памяти.
314 791762
Пытался сделать наклонные блоки 24х24 и вариации почти отвесных обрывов. Пришёл к выводу: либо обрывы полностью плоские и под прямым углом, либо пришлось бы создать очень много вариаций блоков на все случаи жизни, что мне делать лень. Всё же, для проверки ощущений, набросал в Блендере ландшафт, в Годо расставил домики, деревья и текстуры дорог, и немного там покатался. Мне понравилось - со склонами всё выглядит и играется лучше, даже с такими примитивными. Ещё бы детализации блокам добавить, текстуры, мелкие декорации, тогда вообще круто будет, лучше, чем я мог себе представить...

Потом меня осенило: почему я привязался к сетке блоков 24х24? Я могу хранить базовую информацию в прежнем виде, а добавлять на карту блоки размером 12х12. Это позволяет снизить число блоков, т.к. появляется возможность создавать необходимые комбинации прямо в игре. Всё же многие блоки 24х24 состоят из таких повторяющихся деталей 12х12... Это позволило мне сделать наклонные обрывы, которые я могу и планирую детализировать ещё больше (вмятины, камни, корни и т.п., посмотрим). Всё-таки слишком лоупольное лоуполи не так интересно выглядит, но всё лучше плоскости.

Заодно сделал мешлиб из тайлов 12х12 и попробовал использовать редактор GridMap. Что я могу сказать...
1. Гридмап не умеет отражать отдельные блоки (нельзя задать масштаб -1). В апи мешлиб есть возможность задать трансформ мешам, т.е. в теории возможно сделать два блока из одного меша с разными трансформациями, но это нужно проверять.
2. Копипастить/дублировать части карты не получилось. Либо баг, либо я чего-то не понимаю - от клика левой кнопки мыши редактор гридмапы просто закрывается, как будто выбрана другая нода.
3. Можно пикать блоки прямо с карты, но только с того слоя, на котором сейчас редактируешь. Не очень удобно...
4. Вообще управление странное и неудобное. Возможно, я просто не привык. Постоянно случайно смещал выбранный слой, случайно вращал блоки - в самом начале вообще не понял, почему не видно блоков и почему они так вывернуты, пытался переделать мешлиб, пока не вспомнил, что блоки можно вращать...
5. Суммируя с багнутостью визуального интерфейса мешлибов можно сделать вывод, что гридмапами редко и мало кто занимается, поэтому их до сих пор не привели в порядок. Жаль. Но визуальный редактор мне не особо нужен, в любом случае процедурно буду заполнять карту и, вероятно, мешлиб.
6. Да, я задолбался делать коллиженшейпы каждому блоку вручную, хоть это и пара кликов, но всё равно напрягает. Учитывая количество будущих блоков и потенциальных правок... Хорошо бы это всё автоматизировать, тем более что апи есть.
7. А, ещё мои блоки выглядят слишком одинаково в палитре блоков, но это я виноват, что не дал им нормальные имена и порядок.

Хочется поскорее попробовать сделать модули домиков, домики и что-нибудь вроде парка (мелкие блоки есть), но я уже засыпаю. Хорошо хоть идею с 12х12 успел реализовать...
314 791762
Пытался сделать наклонные блоки 24х24 и вариации почти отвесных обрывов. Пришёл к выводу: либо обрывы полностью плоские и под прямым углом, либо пришлось бы создать очень много вариаций блоков на все случаи жизни, что мне делать лень. Всё же, для проверки ощущений, набросал в Блендере ландшафт, в Годо расставил домики, деревья и текстуры дорог, и немного там покатался. Мне понравилось - со склонами всё выглядит и играется лучше, даже с такими примитивными. Ещё бы детализации блокам добавить, текстуры, мелкие декорации, тогда вообще круто будет, лучше, чем я мог себе представить...

Потом меня осенило: почему я привязался к сетке блоков 24х24? Я могу хранить базовую информацию в прежнем виде, а добавлять на карту блоки размером 12х12. Это позволяет снизить число блоков, т.к. появляется возможность создавать необходимые комбинации прямо в игре. Всё же многие блоки 24х24 состоят из таких повторяющихся деталей 12х12... Это позволило мне сделать наклонные обрывы, которые я могу и планирую детализировать ещё больше (вмятины, камни, корни и т.п., посмотрим). Всё-таки слишком лоупольное лоуполи не так интересно выглядит, но всё лучше плоскости.

Заодно сделал мешлиб из тайлов 12х12 и попробовал использовать редактор GridMap. Что я могу сказать...
1. Гридмап не умеет отражать отдельные блоки (нельзя задать масштаб -1). В апи мешлиб есть возможность задать трансформ мешам, т.е. в теории возможно сделать два блока из одного меша с разными трансформациями, но это нужно проверять.
2. Копипастить/дублировать части карты не получилось. Либо баг, либо я чего-то не понимаю - от клика левой кнопки мыши редактор гридмапы просто закрывается, как будто выбрана другая нода.
3. Можно пикать блоки прямо с карты, но только с того слоя, на котором сейчас редактируешь. Не очень удобно...
4. Вообще управление странное и неудобное. Возможно, я просто не привык. Постоянно случайно смещал выбранный слой, случайно вращал блоки - в самом начале вообще не понял, почему не видно блоков и почему они так вывернуты, пытался переделать мешлиб, пока не вспомнил, что блоки можно вращать...
5. Суммируя с багнутостью визуального интерфейса мешлибов можно сделать вывод, что гридмапами редко и мало кто занимается, поэтому их до сих пор не привели в порядок. Жаль. Но визуальный редактор мне не особо нужен, в любом случае процедурно буду заполнять карту и, вероятно, мешлиб.
6. Да, я задолбался делать коллиженшейпы каждому блоку вручную, хоть это и пара кликов, но всё равно напрягает. Учитывая количество будущих блоков и потенциальных правок... Хорошо бы это всё автоматизировать, тем более что апи есть.
7. А, ещё мои блоки выглядят слишком одинаково в палитре блоков, но это я виноват, что не дал им нормальные имена и порядок.

Хочется поскорее попробовать сделать модули домиков, домики и что-нибудь вроде парка (мелкие блоки есть), но я уже засыпаю. Хорошо хоть идею с 12х12 успел реализовать...
315 791802
>>90337

>C фильтрацией мышки поработай. Дёрганая она у тебя.


А у меня >>91762 нормально с этим? Снимал в 60 фпс.
316 791809
>>91802
C мышкой у тебя норм, но у тебя другая проблема. Камера жёстко прибита к машине, из-за этого, когда машина движется, заметны микроджиттеры физона. Я бы рекомендовал депрецированную интерполятед-камеру юзать (ну или взять её код и отвелосипедить себе, если тег депрекатед смущает).
317 791823
>>91809

>Камера жёстко прибита к машине


Да, знаю об этом. С камерой вообще не совсем понятно, сначала делал отдельную камеру каждой машине, сейчас оставляю работать камеру персонажа, но, похоже, она должна быть отдельной от других объектов. Моя камера - орбитальная с возможностью переключиться в режим от первого лица (радиус орбиты = 0), собственно из-за этого второго режима я пока не делал слежение камеры за игроком/машиной. Будет очень странно выглядеть вид от первого лица в перевёрнутой машине, если камера постоянно вертикально ориентирована... Разве что сделать две камеры и переключаться между ними. Нужно подумать.

>заметны микроджиттеры физона


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

Собственно мне даже нравится то, что камера реагирует на движения машины. Если бы камера имела высокую инерцию, движения машины ощущались бы слабее. Если делать камеру совсем отдельно от машины и игрока, придётся искусственно добавлять ей толчки от столкновений и всё такое...
318 791865
>>91823
Я предпочитаю делать слоты для камеры на объектах, обычный Spatial который направлен туда, куда будет смотреть камера. В процессе игры, если надо куда-то переместить камеру, у неё в таргет скриптом прописывается требуемый слот. Камера при помощи интерполяции делает всё остальное. Непонятно, зачем от неё отказались, впрочем, сделать интерполяционное слежение обычной камеры за выбранной нодой не представляет проблемы.

Самый главный плюс - за счёт интерполяции сглаживаются вот эти вот подрагивания.
Есть и минус - нужно следить за коэффициентом интерполяции. Если скорость таргет-ноды слишком увеличивается, камера начнёт отставать, следовательно, коэффициент нужно корректировать пропорционально скорости таргета.
319 791947
Попытался надстроить на свою орбитальную камеру функцию интерполированного сдвига за целью. С толкнулся с рядом проблем, но самых главных две:
1. Мой способ помещения игрока в автомобиль конфликтует с камерой. Либо писать кучу костылей, либо менять способ. Я не знаю, как правильно помещать персонажа в автомобиль, чтобы потом сделать соответствующие анимации, пока что просто помещаю ноду игрока в потомки ноды автомобиля.
2. Нода VehicleBody, судя по всему, не обновляет вовремя global_transform.origin своих потомков, поэтому камера от первого лица продолжает отставать от головы игрока, даже если я пытаюсь скопировать origin головы игрока в origin камеры (SpringArm). Если же в режиме от первого лица вызвать set_as_top_layer(false), тогда я возвращаюсь к старому варианту с фиксированной относительно автомобиля камерой...

В остальном такой эффект запаздывания камеры мне нравится. От первого лица, наверное, нужно не камеру двигать, а голову персонажа перемещать соответственно ускорениям автомобиля, но для этого желательно иметь полноценную модельку со скелетом и анимациями, а не плейсхолдер... Также я подозреваю, что нужно делать свою собственную физическую модель автомобиля, чтобы иметь больше контроля за его положением, а то это запаздывание origin напрягает (ещё напрягают колёса, какие-то они неправдоподобные: не имеют ни веса, ни чётких коллизий, подделка какая-то).

>>91865

>Если скорость таргет-ноды слишком увеличивается, камера начнёт отставать, следовательно, коэффициент нужно корректировать пропорционально скорости таргета.


Разве это не тот эффект, которого мы пытаемся добиться использованием интерполированной камеры? Чем быстрее объект, тем дальше он смещается от центра камеры, демонстрируя свою скорость/резкость. Другое дело, что нужно настроить интерполяцию соответственно самому быстрому отслеживаемому объекту. А если величина запаздывания камеры будет одинаковой для всех объектов, тогда будет сложно оценить реальную скорость объекта на глаз...
320 791953
>>91947

> как правильно помещать персонажа в автомобиль


Отключать ему физику. Да, совсем.
321 791984
А где делаются 2д картинки?
322 791987
>>91986 (Del)

>. рисование от руки. Krita.


мышью?
но это крайне неудбно же
323 791991
>>91990 (Del)
капец,2д выходит дороже 3д
324 791994
>>91993 (Del)
это,скинь ссылку на гайд,почитать
325 791995
>>91952 (Del)

>Ты это делаешь в physics_process?


Да, конечно. Сначала попробовал в _process, потому что камера, по идее, может двигаться быстрее обработки физики, но там был какой-то страшный расколбас: камера вибрировала, как бы пытаясь быть в двух положениях сразу. Поэтому переключил на _physics_process.

>>91953

>Отключать ему физику. Да, совсем.


Это шутка такая что ли? В этом видео >>91762 разве не видно, что у персонажа выключена физика? Иначе машину расколбасило бы во все стороны или она не смогла бы ехать (не помню точно, что-то такое было). Я просто не понимаю, как в играх персонаж визуально открывает дверь, забирается в машину, закрывает дверь, берёт руль в руки и дальше может головой вертеть и прочее подобное...

В общем, я немного погуглил и ничего толкового не нашёл. Есть готовые ассеты на юнити, но они платные. Есть туториалы, опять же на юнити, но там без анимации, тупо телепорт в машину как у меня, персонажа в машине даже не видно. Ну и ладно, у меня уже есть идея, как это можно сделать (в стиле ГТА):
1. Персонаж получает команду "сесть в машину".
2. Подходит к ближайшей двери машины на строго определённую позицию, если это возможно, либо отказывается (иначе начнёт вертеться или анимация будет выглядеть неправильно).
3. Физическая модель персонажа остаётся на месте, а визуальная моделька воспроизводит анимацию "открывание двери и залезание в машину". Параллельно с этим машина воспроизводит анимацию открывания соответствующей двери (если дверь есть).
4. Если произойдёт воздействие на физическую модель персонажа или машины, анимация будет прервана и персонаж не попадёт в машину, а у двери машины включится физика.
5. Если ничто на физические модели не подействует, то после завершения анимаций (сколько-то секунд) физическая модель персонажа отключается, а визуальная моделька становится потомком машины, после чего может продолжать делать другие анимации.
6. Выход из машины в обратном порядке, а если физической модели персонажа что-то помешает, он "вылетит" из машины быстрее обычного, прервав спокойную анимацию. Либо можно включать физическую модель уже после анимации...

Теперь я уверен, что в самой серии ГТА именно такой алгоритм используется: вспомнились очень характерные особенности, которые можно объяснить этим алгоритмом, например, когда персонаж тянет несуществующую дверь, едет в воздухе вместе с машиной, прерывается ударом персонажа или статичного физического объекта со стороны и т.д. Странно, что раньше я думал о сложной симуляции, а тут скорее всего тупо синхронные анимации.

Нужно будет как-нибудь попробовать это сделать, но для этого нужен персонаж со скелетом, а для него нужно определиться со стилем и научиться делать все эти анимации... Негативный опыт прошлого сильно демотивирует( Готовое брать не хочу, если только чтобы посмотреть, как оно устроено.
325 791995
>>91952 (Del)

>Ты это делаешь в physics_process?


Да, конечно. Сначала попробовал в _process, потому что камера, по идее, может двигаться быстрее обработки физики, но там был какой-то страшный расколбас: камера вибрировала, как бы пытаясь быть в двух положениях сразу. Поэтому переключил на _physics_process.

>>91953

>Отключать ему физику. Да, совсем.


Это шутка такая что ли? В этом видео >>91762 разве не видно, что у персонажа выключена физика? Иначе машину расколбасило бы во все стороны или она не смогла бы ехать (не помню точно, что-то такое было). Я просто не понимаю, как в играх персонаж визуально открывает дверь, забирается в машину, закрывает дверь, берёт руль в руки и дальше может головой вертеть и прочее подобное...

В общем, я немного погуглил и ничего толкового не нашёл. Есть готовые ассеты на юнити, но они платные. Есть туториалы, опять же на юнити, но там без анимации, тупо телепорт в машину как у меня, персонажа в машине даже не видно. Ну и ладно, у меня уже есть идея, как это можно сделать (в стиле ГТА):
1. Персонаж получает команду "сесть в машину".
2. Подходит к ближайшей двери машины на строго определённую позицию, если это возможно, либо отказывается (иначе начнёт вертеться или анимация будет выглядеть неправильно).
3. Физическая модель персонажа остаётся на месте, а визуальная моделька воспроизводит анимацию "открывание двери и залезание в машину". Параллельно с этим машина воспроизводит анимацию открывания соответствующей двери (если дверь есть).
4. Если произойдёт воздействие на физическую модель персонажа или машины, анимация будет прервана и персонаж не попадёт в машину, а у двери машины включится физика.
5. Если ничто на физические модели не подействует, то после завершения анимаций (сколько-то секунд) физическая модель персонажа отключается, а визуальная моделька становится потомком машины, после чего может продолжать делать другие анимации.
6. Выход из машины в обратном порядке, а если физической модели персонажа что-то помешает, он "вылетит" из машины быстрее обычного, прервав спокойную анимацию. Либо можно включать физическую модель уже после анимации...

Теперь я уверен, что в самой серии ГТА именно такой алгоритм используется: вспомнились очень характерные особенности, которые можно объяснить этим алгоритмом, например, когда персонаж тянет несуществующую дверь, едет в воздухе вместе с машиной, прерывается ударом персонажа или статичного физического объекта со стороны и т.д. Странно, что раньше я думал о сложной симуляции, а тут скорее всего тупо синхронные анимации.

Нужно будет как-нибудь попробовать это сделать, но для этого нужен персонаж со скелетом, а для него нужно определиться со стилем и научиться делать все эти анимации... Негативный опыт прошлого сильно демотивирует( Готовое брать не хочу, если только чтобы посмотреть, как оно устроено.
326 792004
>>91995

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


Это всё анимации. И они организованы в древовидную стейтмашину.

> Это шутка такая что ли? В этом видео >>91762 разве не видно


Видео смотрел мельком. Сорян если что не так.
327 792011
>>91991

>капец,2д выходит дороже 3д


Вот только для 3д нужно ебейши комп, если хочешь сделать хотя бы маломайский нормальный скульпт, минимуму 4к текстуры и вишенку на тортике в виде рендера 20 секундного видео в 4к не за 2 недели рендера, а за несколько часов
328 792012
>>91991
алсо, для 3д тоже планшет нужен, конкретно для скульптинга
329 792014
>>92011
обычный кубик я буду неделю делать?
330 792015
>>92014
в блендер шифт A и вставляешь готовый куб.
без иронии, когда хочешь порендерить хотя бы симуляцию ткани, то столкнешься с тем, что твой комп кал.
331 792018
>>92015
а что такое рендерить и зачем?
image.png148 Кб, 1280x720
332 792024
тест.webm187 Кб, webm,
300x300, 0:20
333 792065
>>91995

>научиться делать все эти анимации...


С базой вроде разобрался. Оказывается, это так просто!

Осталось только понять, как сделать миленькую мультяшную модельку, которую можно будет безболезненно резать на модули для кастомизации. Пока всё что я делал - некрасиво или слишком детально, непонятно как резать на модули. Всё что нахожу в интернете - тоже не нравится...
334 792097
>>91491
Подключил систему динамической прогрузки карты
В качестве основы взял вот этот темплейт: https://github.com/Yogoda/ZoneLoadingSystem
Самое важное тут - это загрузка комнат в отдельном потоке и инстанс их только когда нужно. Теперь я могу закидывать в комнаты кучу свистоперделок, которые не будут подгружаться и работать.

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

В этом случае для примера для всех комнат я установил одну общую сцену и распределил это дело по сетке, но суть от этого не меняется.

Рекомендую всем к ознакомлению данный репозиторий
335 792099
>>92015
Тогда мне путь закрыт
336 792120
>>92117 (Del)
А там по правилам можно вкидывать начатые игры до конкурса?
337 792124
>>92099
Анончик, ты можешь до 2 миллионов делать модельку поидее, в лоупольке попробовать себя, текстуры снизить. Просто с инструментами познакомиться и что-то сделать. Но апгрейд конечно нужен, явно.
338 792132
>>92120
Напиши в реадми.тхт что заготовочка на НН% и кидай

мимо орг тдг
339 792181
Хто зароботал хоть 10 баксов?
340 792220
>>92181
Хуан
341 792304
>>92280 (Del)
MIght & magic что ты делаешь? ахаха прекрати.
342 792340
>>92097
Для всех спецэффектов я выделил отдельный синглтон, через который их можно вызвать в любой момент игры.
Сам синглтон имеет тип Tween.

Все ноды, которые будут использоваться для эффектов в своем _init() сами указывают себя Effects.shock_wave_rect = self

Ссылка на шейдер волны: https://godotshaders.com/shader/positioned-shockwave/
343 792361
Начал сегодня осваивать AnimationTree. Благодаря встроенной документации легко и быстро разобрался с тем, как его настраивать и использовать, это хорошо. Но так же быстро накнулся на баг:
https://github.com/godotengine/godot/issues/16569
Который висит минимум 4 года и на него практически никто не обращает внимание, все костылят сомнительными путями. Неужели так сложно пофиксить и/или это никого не беспокоит?

Печаль.

>>92340

>шейдер волны


Убери этот ПЕРДЫХ, он не подходит твоей пиксельной графике. Имхо, раз уж у тебя пикселяч, то и все спецэффекты должны быть вручную отрисованы покадровой анимацией, без шейдерной магии. Это как с векторными менюшками, вызывает диссонанс, напрягает. В конце концов это безвкусица, имхо, смешивание принципиально разных стилей, с разной аудиторией и целями.
344 792368
>>92361
ПЕРДЫХ для примера. По итогу он даже не особо заметен будет с нужными настройками.

>спецэффекты должны быть вручную отрисованы


Отрисуй мне
Vid4.mp44,5 Мб, mp4,
960x540, 0:20
345 792389
>>92340
>>92368
По итогу пришел вот к такому варианту. Мне очень нравится, как сочно получилось с небольшим скриншейком и фрейм фризом на 0.1 сек перед рывком.
346 792428
>>92389

>фрейм фризом на 0.1 сек перед рывком


Уже вижу как в движкосраче репостят твоё видео каждую неделю как пример "пропуков каждые 2 секунды на годоте". Имхо, если ты хотел изобразить "зарядку" способности, это нужно было сделать как-то иначе, а не простым фризом. Простой фриз выглядит так, будто это игра лагает при применении способности... Попробуй добавить каких-нибудь частиц, которые активно вылетают из персонажа, пока он замирает в воздухе, чтобы игрок видел, что это не фриз игры, а так задумано. Главное чтоб частицы плавно летели...

>>92365 (Del)

>называть в блендере зацикленные анимации на -loop


Читал про это, но там предлагалось ещё другое решение: сохранить сцену как tscn или создать новый AnimationPlayer... Короче, что-то не так с импортом, почему-то галочка loop не работает, если ресурс автоматически импортирован.

Кстати, о названиях анимаций. Называть их в snake_case? Но тогда с суффиксом это snake_case-loop выглядит ужасно.
Или делать шашлык-кейс-loop?
Или вообще нужно ПаскальКейс-loop?
Судя по документации, в AnimationTree стейты предлагается называть с маленькой буквы, но по умолчанию они копируют названия экшонов из AnimationPlayer...

Все эти различия в кейсах названий напрягают и раздражают(
инбифо выбери что нравится: я не знаю что мне нравится
347 792442
>>92428

>движкосраче репостят


Там и без этого буду шедевры годота постить

>Попробуй добавить каких-нибудь частиц


Просто не нужно было замедлять все до 0 и сделать плавную анимацию в виде импульса как на пике 2. В итоге новых партиклов не нужно добавлять
348 792458
>>92361

>AnimationTree


Доделал и баг обошёл, действительно -loop помогает.
Кстати, в документации вместо -loop встречается -cycle.

На видео красная маршмэллоу сделана только на AnimationPlayer, а зелёная маршмэллоу сделана только на AnimationTree, которая на скриншоте (анимации stand-wave в видео нет).

Сейчас меня напрягает один вопрос: а как определять, что анимация завершилась? Ведь в скрипте персонажа тоже должны быть состояния персонажа, и, по идее, персонаж не может резко переходить из одного состояния в другое, пока не закончится анимация. К примеру, если спамить "присесть", будет много запросов на переключение анимации - и пусть AnimationTree правильно отображает последовательность действий, но резкое нажатие кнопки атаки создаст задержку между собственно атакой и отображением анимации атаки... Т.е. нужно определять, когда персонаж действительно вошёл в требуемое состояние, чтобы синхронизировать скрипты и анимации.

Ожидал обнаружить механизм на базе сигналов, но сигналов в системе анимации почти нет. Во всяком случае, я не нашёл сигнала типа "state_changed(new_state)". Есть метод get_current_node(), позволяющий определить текущее состояние конечного автомата, но неужели я должен проверять это состояние каждый кадр, дожидаясь переключения в нужное мне состояние?

Прочитал статью про использование AnimationTree в руководстве, но там только общая информация о том, как управлять конечным автоматом. Может быть, я что-то не так понимаю? Может, мне не обязательно знать, когда анимация завершится? Но, скажем, если для атаки нужно сначала достать оружие, а доставание оружия занимает какое-то время, как определить, что атака уже началась и можно поставить состояние в коде типа "state = State.ATACK"?

Ладно, возможно, я думаю сейчас о проблемах, которых на практике нет, потому что я ещё даже не начал делать персонажа и полноценные игровые анимации...
349 792479
>>92458

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


Как это решил для себя я. Просто расставил в самих анимациях вызовы методов. Таким образом они происходят идеально синхронно с анимацией.
Допустим, персонаж бьёт холодным оружием. Часть времени уходит на замах, и когда оружие оказывается впереди него, из анимации вызывается метод enable_blade(), у лезвия включается коллизия, оно режет всех, кого надо резать; в конце анимация вызывает disable_blade(), после чего оружие безопасно доводится до конца своей траектории.
Ещё, кстати, из анимации удобно синхронизировать звук шагов с собственно шагами.
350 792505
>>92238 (Del)
Про реалии геймдева
351 792507
>>92506 (Del)
Годот?
Жанр какой?Какая динамика с момента публикации?
352 792510
>>92509 (Del)
Ответ на 3 вопроса ничего не спалят
353 792512
>>92509 (Del)
Отправил поделку Фальке?
354 792515
>>92514 (Del)
При чем тут его движок?
355 792520
>>92518 (Del)
Логичнее обсуждать движки в движкосраче.
356 792527
Годот 4 сделает некоторые туториалы по 3 нерабочими?
357 792531
>>92527
Не сказать что нерабочими. Просто в некоторых случаях придется что-то допиливать до новой версии движка. Сильно перелопатили 2д и 3д физику, ноды переименовали и добавили новые, GDScript обновили и так далее.

Почитай https://godotengine.org/article/dev-snapshot-godot-4-0-alpha-1
358 792534
>>92532 (Del)

>у самого тела будет параметр linear_velocity



Пиздец жду на самом деле беты чтоб затестить новый CharacterBody.

Имхо, гораздо более удобная штука чем KinematicBody.

Из приятных фич выделю MovingPlatformApplyVelocityOnLeave (Позволит прыгать с двигающихся платформ, сохраняя скорость) , get_last_motion()(Вернет вектор последнего перемещения), get_real_velocity() (Вернет настоящую скорость тела, например если ты стоишь на двигающейся платформе, или если поднимаешься по склону, то motion_velocity будет горизонтальной, а эта функция вернет диагональ)

Мимо платформер-кун
359 792536
>>92534
Ну и еще будет гораздо проще интегрировать ускорение. Добавляем телу переменную Vector2 acceleration и уже меняем его. Каждый фрейм он сбрасывается и просчитывается с нуля. После чего просто добавляем к motion_velocity нашу acceleration
360 792540
>>92532 (Del)
Ну пару лет все новички будут пилить на 3ке
361 792550
>>92506 (Del)
Повезло
362 792552
>>92527
Для начинающих да. Для продолжающих нет.
Плюс это неплохая возможность вкатиться в создание видеотуторов, пока нет обучающих материалов на русском языке.
363 792555
>>92552
Ну 4 наверно будет к концу 22г,а ее исправления в 23 кек
364 792561
>>92559 (Del)
Строчить гнвные посты что ниче не работает и нет гайдов?
365 792565
>>92559 (Del)

> ладно не буду писать что они будут делать


Охуенно я вас построил.
Vid5.mp418,1 Мб, mp4,
1920x1080, 0:31
366 792572
>>92389
Сегодня опять твикал физику и допиливал систему комнат.

Решил дернуть вот этот ассет https://pixelfrog-assets.itch.io/kings-and-pigs и мне понравилось.

Над визуальными эффектами еще немного поработал. Что скажете?

inb4 "Ряяя не пиксельный круг" - долго обьяснять, почему я решил так сделать, и об этом можно бесконечно спорить. Это осознанное решение и сводится к тому, что это не часть мира, в котором обитает персонаж.
367 792578
>>92572

>"Ряяя не пиксельный круг


Дык у тебя и другие vfx эффекты не пиксельные, а шейдеры ломающие пиксель шаг
368 792580
>>92555
Ну, Пахом пока что вообще не собирается что-то делать, так что хуй знает. Правда у него в голове уже все продумано...
369 792626
>>92578
Мне кажется любую современную пиксельную игру возьми, там будут шейдеры с пост-эффектами. Это только пуристы ворчат.
370 792627
>>92572
А вот этот серый кирпич с лицом будет что-то делать? ИМХО слишком толстая отсылка на Селесту.
Vid6.mp413,1 Мб, mp4,
1920x1080, 0:36
371 792630
>>92627
Насчет Селесты - я и не скрывал, что вдохновлялся ей.
Насчет кирпича - графику рисовал не я, это фри ассет. Как будет готова демка хочу найти художника и скооперироваться с ним для запила полноценной игры
372 792636
>>92630

>Насчет Селесты - я и не скрывал, что вдохновлялся ей.


Вдохновляться Селестой - не что-то плохое. В предложении "ИМХО слишком толстая отсылка на Селесту" в негативном ключе было употреблено только слово "слишком", остальные слова несут строго нейтральный смысл.
Тащемта если фри ассет, то никаких вопросов.
Лично мне больше нравился анимированный фон, кстати, он такой психоделичный. Но мои вкусы обычно специфичны.
373 792640
>>92636
Твои слова о психоделичном фоне натолкнули меня на одну идею.

Герой поднимается на башню и чем выше он, тем более дырявые стены(фоновые) становятся и через дырки все сильнее проглядывается вот этот анимированный фон.
gif6-1.gif3,8 Мб, 480x360
374 792659
>>92626
Двачую. Если выглядит заебись, нахуй в хуй дуть спрашивается. Мне и самому заходит подобное.
375 792720
>>92659

>выглядит заебись


пик нерелейтед надеюсь?
выглядит вульгарно, как дешевка, сделанная от неумения нарисовать нормально, которой оно и является.
376 792881
>>92720
вообще-то большинству игроков зашло же, не понимаю бугурта. оценивает покупатель, в случае игр, творчество ради творчества утопия. Сомневаюсь в том, что если бы не было всех этих свистоперделок, то графоний бы выглядел бы так же пёстро. Автор кстати и вправду плохо рисует и путем добавления эффектов скрыл этот факт. Или ты будешь йобо Кирюшей, который до идеала выдрочит пиксели и только потом выпустишь игру? Спустя 20 лет. Звучит комично.
377 792887
>>92720
пффф... ну сделай лучше. просто смешно читать такой бред.
# OP 378 792890
Пришло время обсудить, что добавить в шапку, что убрать. Ожидаю ваших предложений, годаны. Арт для оп-пикчи тоже приветствуется.
379 792892
>>92890
godotshaders добавь
380 792893
381 792895
>>92892
Изучу вопрос.
>>92893
Они постоянно из репа в реп скачут. Вроде бы десяток тредов назад ссылка была как раз предыдущая. Окей, рассмотрю.
382 792897
Ну и можешь добавить https://steamdb.info/tech/Engine/Godot/
Игры в стиме, сделанные на Годо.
383 792899
>>92898 (Del)
а экспорт там есть кста?
1645599641657.jpg59 Кб, 404x303
384 792901
>>92892

> godotshaders


Хоспаде, какая годнота!
385 792902
[2D] Имеем:
1. кинематик двигается через move_and_slide_with_snap.
2. Все наклонные плоскости не более 45 градусов, а в функции указывается чуть больший угол.
3. Вектор снапа указан верно.
И вообще. Всё правильно работает, персонаж снапится к земле, правильно проходит все изгибы. Кроме одного. Вот такого подъём в горку, затем плато, а затем резкий 90 градусов обрыв. Что происходит? Знающие люди знают: персонаж поднимается в горку, добегает до обрыва и без команды подпрыгивает. Если мониторить велосити, то можно обнаружить, что после горки её вектор направлен под углом к горизонту и почему-то не приходит в горизонтальный, даже несмотря на то, что заснапленный персонаж движется ровно по горизонтали.
Я думал, думал. И пришёл к простому решению:
var old_pos = position
move_and_slide_with_snap(.....)
velocity = (position - old_pos) / delta
И всё! Пока что ни одного бага, который мог бы появиться от неправильного использования кинематиков, не замечено. Ну типа, я ожидаю от move_ans_slide_with_snap, что оно вернёт мне велосити с поправкой на снап; оно не возвращает, но я получаю самостоятельно, в результате поведение выходит как раз как я ожидаю.
Но вот что меня смущает. Я предварительно хорошенько прогуглил эту проблему. И среди всех возможных решений НЕТУ моего варианта. Естественно закрадывается подозрение, что я что-то делаю не так. Но всё ж работает. Тогда зачем народ пляшет с бубном и ищет сложные решения? Непонятно. Что думаете?
386 792904
>>92898 (Del)
Есть ссылка на офсайт, а там уже анон сам разберётся, что качать. Мне кажется перегружать шапку ссылками на скачку определённых версий - избыточно.
1645600612557.png389 Кб, 1718x2113
Перекатил # OP 387 792906
388 792925
>>92902
Как ты гравитацию реализовал? Судя по всему проблема в том что её нет
Тред утонул или удален.
Это копия, сохраненная 5 августа 2023 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /gd/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски