Godot #62 # OP 1014044 В конец треда | Веб
Добро пожаловать в тред любви, взаимопомощи и создания сцен в рантайме при помощи ResourceSaver!
Шапка: https://hipolink.me/godothread
Предыдущий:
>>1008211 (OP)
Архивный: >>1000909 (OP)
2 1014047
первый
3 1014048
>>4044 (OP)

>суть.gif


>решение.gif


Ты троллишь? Это не имеет отношения к движку...
Лучше бы запостил прозрачный рендер с бликами.
4 1014050
>>4047
Первый сделал игру? Первый пришел к успеху? Первый в топчартах стима?
GigaGodot.jpeg270 Кб, 1566x2048
5 1014054
Не забывайте: даже если вы в данный момент не делаете игру, Godot внимательно смотрит на вас.

Делайте игру.
6 1014056
>>4054
Я не геймдизайнер, мне это неинтересно. Я лучше какую нибудь симуляцию запилю.
7 1014058
>>4056

>лучше какую нибудь симуляцию


Но симуляции это тоже игры...
https://en.wikipedia.org/wiki/Non-game
https://en.wikipedia.org/wiki/Simulation_video_game
Покажешь свои симуляции?
8 1014062
>>1014000 →

>в Годо есть встроенное решение для undo/redo!


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

>>4048

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


Или Jiggle-физику
9 1014070
>>4062

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


И люто бесит. Когда ты нажимаешь ctrl+z, отмена происходит там, где ты сейчас сфокусировался... Например, если хочешь отменить удаление ноды - нажимаешь на дерево сцены, а если параметров материала - на инспектор материала. Дико бесит, особенно когда меняешь всё и сразу, понемногу.

Привык, что полагаться на undo/redo в Godot нельзя.
10 1014073
>>1014033 →
https://docs.godotengine.org/en/stable/classes/class_undoredo.html
>>4070
Это еще ладно. Бывает, что оно вообще перестает работать и начинает удалять какие-то рандомные строки кода вместо undo. Помогает только перезапуск редактора.
11 1014077
>>4073
А ты историю изменений пробовал? В какой-то версии реализовали - по умолчанию там, где инспектор, вроде третья вкладка. По идее, глобальный откат/повтор, но лично я выключил это меню в настройках (кажется, тормозило, не помню уже; нужно ещё попробовать).

Впрочем, обычно ничего кроме одного ctrl+z не нужно.
1651661772599.mp426,5 Мб, mp4,
1920x1080, 1:04
12 1014085
>>4058
Нет, свои не покажу.
wat.png8 Кб, 756x60
13 1014087
Кстати, как вы справляетесь с тем, как Godot часто избыточно пересохраняет никак не изменявшиеся ресурсы (tres)? По-моему, замедляет сохранение.

Баг древний, но его почему-то игнорируют:
https://github.com/godotengine/godot/issues/31186

Меня задолбало... Как оптимизировать структуру проекта, чтоб избежать этих лишних сохранений? Пробовал закрывать все вкладки сцен - пикрил...
14 1014101
Хочу вот так:

>if get_some_object() is MyType obj:


> > obj.do_my_func()


Когда сделоют?
15 1014102
Локализация в годоте делается изи-изян. Зря забивал на локализацию своих прошлых игр.
16 1014105
>>4087
Хз, сам не встречал этот баг, хотя гитом пользуюсь с 3.х. Думаю он не столько про замедление сколько про замусоривание лога гита.
image.png210 Кб, 585x699
17 1014115
Делойте игоры
18 1014117
>>4115
Я не могу.
Я пьян.
19 1014119
>>4117
Делай пьяные игры. Симулятора алкоголика еще, вроде, не было.
20 1014127
>>4101
Самый простой способ с переменной:

>var obj := get_some_object() as MyType


>if obj: obj.do_my_func()


Если объект не MyType, то в obj будет null.

Разница между is и as:
obj is T == true/false (bool)
obj as T == obj/null (T)

В условиях:
null == false
instance == true
freed_instance == false
Поэтому можно делать так:

>if obj: # если obj создан и пока существует...



Если другие типы недопустимы, лучше так:

>(get_some_object() as MyType).do_my_func()


Это упадёт с обращением к null если не MyType.

>>4119

>Симулятора алкоголика еще, вроде, не было.


Было уже несколько, это банальная идея...
21 1014130
>>4127
Мне нравится когда в условии if создаётся локальная переменная и к ней подтягивается автодополнение редактора. Сделойти.
22 1014135
>>4130

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


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

>подтягивается автодополнение


Здесь оно тоже подтягивается:

>var obj := get_some_object() as MyType


>if obj: obj.do_my_func()


И здесь тоже подтягивается:

>(get_some_object() as MyType).do_my_func()


Алсо, GDScript позволяет форматировать так:

>var obj := get_some_object() as MyType; if obj:


>_ obj.do_my_func()


Если очень надо, можно всё в одну строчку через ";".

>Сделойти


Делай сам. Но в основную версию вряд ли пустят.
1742656840557.png28 Кб, 377x317
23 1014136
И так не получается. И эдак не получается. Ой, всё. Ну и ладно. Ну и не надо.
24 1014137
>>4135

> Но в основную версию вряд ли пустят.


Они уже очень много притянули из шарпа. Неужели я многого прошу ещё одну фичу притянуть. Из шарпа.
25 1014140
>>4136
Что мешает написать так?

>var s := get_node_s() as Node3D


>if s: print("s is Node3D")


Ты не понимаешь функцию "as"?

>>4137

>очень много притянули


У них строгое правило "не тянуть без надобности".
Создай proposal, пусть люди лайки ставят тебе...
26 1014141
А ещё пора в гдскрипт ввести модификаторы доступа.

> @private @onready var something : String = "hurr durr"



Для обратной совместимости считать все переменные и функции публичными, но добавить аннотацию, которая задаёт режим:

> @private_default

27 1014143
>>4140

> Что мешает написать так?


Очевидно, что мешает необходимость проверять несколько подтипов в цепочке наследования.
28 1014145
>>4141

>модификаторы доступа


https://github.com/godotengine/godot/pull/103768

Ты серьёзно пишешь в своём коде такое?

>other_object._private_var = value


>other_object._private_func()


Это ж максимально неприятно выглядит ("._").
Естественно, что приватное начинается с "_".

>>4143

>проверять несколько подтипов в цепочке


https://ru.wikipedia.org/wiki/Проблема_XY
Конкретно зачем тебе это нужно?

Если в твоём коде часто случается такое:

>если а типа А, то...


>иначе если а типа Б, то...


>иначе если а типа В, то...


>иначе если а типа Г, то...


Тогда тебе нужно учить базу ООП.
https://ru.wikipedia.org/wiki/SOLID

Реальное решение будет выглядеть так:

>get_object().do_work() # никаких проверок


В каждом классе - свой личный do_work().
29 1014152
>>4145

>if obj.has_method("do_work"): obj.do_work()

30 1014159
>>4152

>has_method


Вроде бы можно так, и это даже будет побыстрее:

>if "do_work" in obj: obj.do_work()


Но это если у тебя obj может не иметь do_work().

Речь шла про ситуации, когда ты делаешь так (плохо!):

>if animal is Cat: animal.meow()


>elif animal is Dog: animal.bark()


>elif animal is Bird: animal.chirp()


>elif animal is Duck: animal.quack()


>elif animal is Human: animal.shout()


Вместо этого лучше сделать так:

>animal.make_sound()


Cat, Dog, Bird, Duck и Human сами решат, как им звучать.

Если у тебя есть Fish, то у неё тоже есть этот метод:

>class_name Fish extends Animal


>func make_sound() -> void: pass # fish can't make sound


Чтобы не было проверок типа "можешь ли ты звучать".

Суть в том, что ты ПРОСТО создаёшь новый класс:

>class_name Zombie extends Animal


И реализуешь ему все необходимые Animal методы:

>func make_sound() -> void: play_sound("Aaarghhhh!")


ВСЁ. Не нужно никуда добавлять "elif animal is Zombie..."

Для RayCast/ShapeCast/Area лучше всего настроить слои.
30 1014159
>>4152

>has_method


Вроде бы можно так, и это даже будет побыстрее:

>if "do_work" in obj: obj.do_work()


Но это если у тебя obj может не иметь do_work().

Речь шла про ситуации, когда ты делаешь так (плохо!):

>if animal is Cat: animal.meow()


>elif animal is Dog: animal.bark()


>elif animal is Bird: animal.chirp()


>elif animal is Duck: animal.quack()


>elif animal is Human: animal.shout()


Вместо этого лучше сделать так:

>animal.make_sound()


Cat, Dog, Bird, Duck и Human сами решат, как им звучать.

Если у тебя есть Fish, то у неё тоже есть этот метод:

>class_name Fish extends Animal


>func make_sound() -> void: pass # fish can't make sound


Чтобы не было проверок типа "можешь ли ты звучать".

Суть в том, что ты ПРОСТО создаёшь новый класс:

>class_name Zombie extends Animal


И реализуешь ему все необходимые Animal методы:

>func make_sound() -> void: play_sound("Aaarghhhh!")


ВСЁ. Не нужно никуда добавлять "elif animal is Zombie..."

Для RayCast/ShapeCast/Area лучше всего настроить слои.
31 1014160
>>4159

>>func make_sound() -> void: pass # fish can't make sound


Поправка: этот метод скорее всего есть у предка - Animal:

>class_name Animal extends...


>func make_sound() -> void: pass


Многие потомки Animal делают свою версию, но не Fish.

Таким образом любые потомки Animal могут "звучать".
ы.png1 Кб, 166x66
32 1014164
>>4105

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


У меня Godot начал зависать при сохранении.
Сохраняю один простой скрипт - жду секунд 10.

Почему это может быть? Как искать причину?
33 1014177
>>4164
Чекай жёсткий диск. Походу пришло время, его время.
1718606148939.mp4709 Кб, mp4,
640x480, 0:12
34 1014188
35 1014190
>>4101
Это не соответствует парадигме duck typing. Используй has_method.

>>4141
Никогда не понимал, зачем это нужно. Ну ладно, в компилируемых языках, возможно, применяются какие-то оптимизации, которые могут добавить производительности, если правильно разграничить права доступа. Наверное. Но в гдскрипте-то это зачем? Почему нельзя написать коммент "## это приватный мембер" и просто не использовать его извне? Это ж никак не влияет на производительность. Зачем эти искусственные ограничения?
36 1014205
>>4190

> Используй has_method(&"method_name")


У меня детская травма, я не люблю строковые литералы в коде. И даже то что Хуан сделал для таких как я стрингнеймы - не сильно помогает.
37 1014243
>>4205

>стрингнеймы


Это что такое?
625dcd34453484bcb80f4c1869fc0216-4058878128.jpg69 Кб, 736x736
38 1014244
>>4190

>просто не использовать его извне


КАЧАЕШЬ ПРИКОЛЬНЫЙ АДДОНЧИК
@
ОН ПОЧТИ ИДЕАЛЕН ДЛЯ ТВОЕЙ ИГРЫ
@
НАДО ЛИШЬ КОЕ-ЧТО ИЗВНЕ ПОПРАВИТЬ
@
НАХОДИШЬ ИНТЕРЕСНОЕ ПОЛЕ _ПЕРДЫХ
@
ДА ЭТО ЖЕ ЛУЧШАЯ ФИЧА ВСЕГО АДДОНА!
@
СКАЗАНО НЕ ИСПОЛЬЗОВАТЬ, НУ ДА ЛАДНО
@
НИКАКИХ ПОБОЧНЫХ ЭФФЕКТОВ НЕ ВИДНО
@
ОБМАЗЫВАЕШЬ ВСЮ ИГРУ ЭТИМ _ПЕРДЫХ
@
ВСЯ ИГРА СВИСТИТ И ПЕРДИТ - КРАСОТА!
@
ПРОХОДИТ ПАРА МЕСЯЦЕВ РАЗРАБОТКИ
@
ОБНОВЛЯЕШЬ АДДОН ДО ВЕРСИИ 1.0.1
@
ТАМ ФИКС КРИТИЧЕСКОГО ОБДРИСТА
@
БЕЗ НЕГО ИГРА РАСТЕКАЕТСЯ В ЛУЖИЦУ
@
ПРОВЕРЯЕШЬ, КАК ОНО ПОСЛЕ АПДЕЙТА
@
_ПЕРДЫХ ВЕДЁТ СЕБЯ КАК-ТО СТРАННО
@
ПРОЕКТ СЛОМАЛСЯ И БОЛЬШЕ НЕ ПЕРДИТ
@
ВСЯ ТВОЯ ИГРА БЫЛА ПРО ЭТОТ ПЕРДЁЖ
@
РЕШАЕШЬСЯ САМ ПОФИКСИТЬ _ПЕРДЫХ
@
В АДДОНЕ 100500 СТРОК ГОВНОКОДА...
625dcd34453484bcb80f4c1869fc0216-4058878128.jpg69 Кб, 736x736
38 1014244
>>4190

>просто не использовать его извне


КАЧАЕШЬ ПРИКОЛЬНЫЙ АДДОНЧИК
@
ОН ПОЧТИ ИДЕАЛЕН ДЛЯ ТВОЕЙ ИГРЫ
@
НАДО ЛИШЬ КОЕ-ЧТО ИЗВНЕ ПОПРАВИТЬ
@
НАХОДИШЬ ИНТЕРЕСНОЕ ПОЛЕ _ПЕРДЫХ
@
ДА ЭТО ЖЕ ЛУЧШАЯ ФИЧА ВСЕГО АДДОНА!
@
СКАЗАНО НЕ ИСПОЛЬЗОВАТЬ, НУ ДА ЛАДНО
@
НИКАКИХ ПОБОЧНЫХ ЭФФЕКТОВ НЕ ВИДНО
@
ОБМАЗЫВАЕШЬ ВСЮ ИГРУ ЭТИМ _ПЕРДЫХ
@
ВСЯ ИГРА СВИСТИТ И ПЕРДИТ - КРАСОТА!
@
ПРОХОДИТ ПАРА МЕСЯЦЕВ РАЗРАБОТКИ
@
ОБНОВЛЯЕШЬ АДДОН ДО ВЕРСИИ 1.0.1
@
ТАМ ФИКС КРИТИЧЕСКОГО ОБДРИСТА
@
БЕЗ НЕГО ИГРА РАСТЕКАЕТСЯ В ЛУЖИЦУ
@
ПРОВЕРЯЕШЬ, КАК ОНО ПОСЛЕ АПДЕЙТА
@
_ПЕРДЫХ ВЕДЁТ СЕБЯ КАК-ТО СТРАННО
@
ПРОЕКТ СЛОМАЛСЯ И БОЛЬШЕ НЕ ПЕРДИТ
@
ВСЯ ТВОЯ ИГРА БЫЛА ПРО ЭТОТ ПЕРДЁЖ
@
РЕШАЕШЬСЯ САМ ПОФИКСИТЬ _ПЕРДЫХ
@
В АДДОНЕ 100500 СТРОК ГОВНОКОДА...
39 1014246
>>4244
Гит, бекапы
40 1014247
Если считать только донаты, не учитывая прямые инвестиции от гуглов и тд, то годот в год собирает 525 тысяч евро.
41 1014251
>>4247
Хорошо, но лучше больше.
42 1014267
>>4251
Задонать.
43 1014276
>>4267
Как стану миллиардером и перееду на запад - обязательно буду переводить процентов 5% дохода.
1742726652677.jpg46 Кб, 408x439
44 1014282
>>4243
Да действительно, блять, что же это такое? Давайте поможем Даше найти гугл, блять.
45 1014286
>>4246

>Гит, бекапы


Каким образом гит/бэкап поможет тебе обновить посторонний аддон до новой версии, сохранив функциональность игры, которая опиралась на секретную (приватную) возможность, которую ты не должен был использовать и которая изменилась?

С приватными полями всё просто: редактор тебе автоматически по рукам бьёт и говорит "низя". Без приватных полей ты говнокодишь без ограничений.

Это как со слабой типизацией: да, МОЖНО хранить в одной и той же переменой любые данные. Но будут последствия для твоего психического здоровья, при условии, что код проживёт дольше одного вечера.

Ещё более наглядный пример - глобальные данные, синглтоны. Хочешь обмазаться лапшой и дрочить?

Писать говнокод слишком легко - нужен начальник, наказывающий тебя за говнокод автоматически.
1742727701317.png35 Кб, 385x912
46 1014288
>>4286

> Ещё более наглядный пример - глобальные данные, синглтоны. Хочешь обмазаться лапшой и дрочить?


Обоже опять эти ужасные антипаттерны повылезали из под кровати.
a.jpg41 Кб, 736x736
47 1014289
>>4282

>Давайте поможем Даше


Ты чё такой помогающий?

>>4243

>>стрингнеймы


>Это что такое?


https://docs.godotengine.org/en/stable/classes/class_stringname.html
48 1014299
>>4288
Хорошо, делай синглтоны:
Sprite: уникальная аватарка для Player.
Player: принимает ввод и меняет Sprite.pos.
Health: выводит над Sprite.pos здоровье Player.
Enemy: движется к Sprite.pos, снижает Health.value.
Shield: копирует Sprite.pos, поднимает Health.value.
И так далее. Не смей избегать синглтонов в игре.

Потом расскажешь, какой это чудесный паттерн.
49 1014300
>>4286
ПРОСТО откатишься на старую версию, когда все работало. Стремление всегда использовать последнее - болезнь мозга и подвид прокрастинации.
50 1014302
>>4289
Спасибо. Ни разу не встречал. Оно где-то под капотом работает?
51 1014303
>>4300
В версии 1.0 всё работает, но из-за бага компьютер игроков взламывается кулхацкером фалько и жжёт пердаки до температуры поверхности Солнца. Это обнаружили только спустя несколько месяцев.

В весии 1.0.1 баг пофиксили, но из-за него ты будешь вынужден изменить 100500 строчек в проекте. Но и релизить игру с багом из 1.0 тоже недопустимо.

Влошил 100500 трудочасов и теперь откатишь их?

А ты просто заюзал то, что мог, но не должен был...
52 1014306
>>4302

>Ни разу не встречал.


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

>Оно где-то под капотом работает?


Так-то да, но можно использовать вручную, но много непонятных нюансов. По идее StringName - это просто целое число, поэтому их очень легко сравнивать - нет необходимости проверять каждый символ строки. Но преобразование String в StringName занимает много времени, равно как и создание нового StringName... Поэтому лучше их создавать заранее как константы.
53 1014307
>>4299
Перестань строить из себя клоуна. Синглтоны нужны там, где они нужны, на своих местах. Я не буду реализовывать приведённое тобой соломенное чучело, чучело.
54 1014308
>>4307

>Синглтоны нужны там, где они нужны


Приведи примеры, где они обязательно нужны.

Не из API движка, а из твоей собственной игры.

Где ты никак не смог обойтись без синглтона?

Алсо, как новичок определит, где они нужны?
image.png222 Кб, 1113x723
55 1014309
Хуан то кстати отошел от дел.
56 1014312
>>4309
в редот коммитит под виртуалом
image.png46 Кб, 1180x732
57 1014314
>>4312
В редот коммитит примерно никто. Смотрю у них сил не осталось даже на таскание коммитов из годота.

Бля, а вони-то было.
58 1014316
>>4308

> DialogueSingleton.start_dialogue(npc.get_current_lines(), WorldDataSingleton.get_dialogue_point(npc))


Данный код запрашивает у синглтонового менеджера диалогов старт диалога, первый параметр - ресурс со строками диалога в формате жсон, второй параметр - точка на которой был прерван диалог, точка входа. Берется из синглтонового менеджера управления данными для сохранения.
image.png196 Кб, 1294x920
59 1014317
А судя по активности в 3.х ветке годота нас ждет еще и 3.7 версия. Охуенно.
1662718334307.png1,8 Мб, 1408x768
60 1014318
>>4314
Потому что у них нет Блазии-няши....
61 1014319
>>4317
Уже год жду...
62 1014320
>>4318
И ещё эта девочка с мышиными ушками, как её там звать. Тоже топчанская.
63 1014321
>>4320
Думаешь, ей стоит свой форк завести? Как он будет называться? Хопот?
64 1014325
>>4321
Не стоит. Пусть коммитит Хуану.
65 1014368
>>4316

>DialogueSingleton.start_dialogue


>WorldDataSingleton.get_dialogue_point


Что не получится сделать из-за этих синглтонов:
1. Сплит-скрин мультиплеер: нужны от 2 до 4 диалогов.
2. Параллельный разговор с NPC: нужно от 2 диалогов и более.
3. Параллельные вселенные в игре: нужны разные ветки сохранения.
Без синглтонов подобное решается простым созданием экземпляров классов.

Почему ты решил сделать именно так, через очевидно не обязательные синглтоны?
66 1014371
>>4368
Мультиплеерные кнопки подъехали.
67 1014372
>>4371
Аргументов в пользу синглтонов у тебя всё ещё нет. Понятно...
1742744653158.png35 Кб, 385x912
68 1014375
>>4372
Всмысле нет аргументов? Я начал с аргументов. Продублирую.
69 1014386
Главный антипаттерн это игры не делать, находясь в параличе от потенциальных косяков.
70 1014387
>>4386
Делать игры - не что-то обязательное.
71 1014388
>>4387
Зачем ты здесь. Уходи.
72 1014389
>>4388
Нет пусть остается.
73 1014390
>>4388
Я здесь чтобы обсуждать какие-то фичи в движке, которые мне интересны.
74 1014399
>>4375

>...Server..., IP, Input..., Native..., OS, Java..., GDExtension...


Может быть только одним - это прослойка перед железом/ОСью.

>ClassDB, Editor..., Engine..., Performance, Project..., Navigation...


Может быть только одним - это основное API движка, а он один.

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

Не чувствуешь проблему?..
75 1014403
>>4399
Врываюсь в тред на моноколесе, твои контрмеры?
76 1014404
>>4399

>AudioServer может быть только один


>Как же так, баги когда игрок переключается с динамика на Bluetooth


>DisplayServer может быть только один


>Годами приходится добавлять поддержку второго глаза для ВиАр или второй монитор со своим разрешением


>PhysicsServer может быть только один


>Приходится городить костыли когда нужно две разных физических симуляции (например одна для платформера, а вторая для инвентаря).

77 1014409
>>4403
Смеюсь, показываю пальцем и фотографирую.
78 1014410
>>4244

>СКАЗАНО НЕ ИСПОЛЬЗОВАТЬ, НУ ДА ЛАДНО


Вот здесь проблема. В кривых руках кодера, который полез нажимать красную кнопку, на которой написано не нажимать. Не зная, что под капотом эта кнопка делает, почему нажимать нельзя и какие могут быть скрытые последствия.
Это всё равно что засунуть посторонний металлический предмет в розетку, а потом жаловаться, что током ёбнуло - ну ты же смог его туда запихнуть, значит это было можно, да?
1615989612728.jpg4 Кб, 225x225
79 1014411
>>4410
Во дураки, защиту для розеток какую то лепят.
80 1014414
>>4411
Это защита от случайного попадания предметов. От преднамеренного поможет только живительная эвтаназия.
image.png93 Кб, 266x159
81 1014415
Есть идеи как сделать круговой эффект кулдауна без шейдера? Легко сделать заливку сверху-вниз и выдать это за кулдаун, но хотелось бы как положено - круговой.

С шейдером уже сделал. Теперь интересно без.
image.png76 Кб, 792x510
82 1014416
>>4415
Сам спросил, сам ответил.
83 1014417
>>4416
Там под капотом наверняка тоже шейдер.
85 1014419
>>4418
Да, без шейдеров. Оно использует draw_polygon() из https://docs.godotengine.org/en/stable/tutorials/2d/custom_drawing_in_2d.html
86 1014420
Чего бы я делал без годотик-треда. Ебаное одиночество.
1691226210276.mp41,3 Мб, mp4,
1920x1080, 0:15
87 1014424
>>4416
Сегодня мы с тобой клипуем
88 1014425
>>4424
Гениально.
89 1014427
>>4425
Думаю и на видяхе быстрее клиповать чем рисовать полигоны или шейдерить.
90 1014428
>>4427
А вдруг клипуется шейдером? Ну там, под капотом.
91 1014436
Ну и че этим красноглазикам так не нравится иф елс?
Работает же. Нахуя тогда вобще в яп добавляют условия?
92 1014438
>>4436
поч не нравится? мне все нравится. главное не делать много этажей.
93 1014444
>>4427
Разве такой уж большой будет выигрыш по скорости? Лучше делать игру, чем оптимизон
94 1014445
>>4428
Наверняка там под капотом клипуется синглтоном.
95 1014458
>>4428
Так, важен не факт наличия шейдера, а тяжелость его вычислений.
Например шейдеры который лежит на godotshaders выглядит очень тяжелым.
Во первых там fragment(), это вычисления для каждого пикселя, а не для полигона. И они все с синусами. С нодой по идее один раз считается при повороте (ну может еще раза 4 для вершин прямоугольрника).
Во вторых там if, в шейдерах это насколько помню сбивает конвеер.
А clip, скорее всего, превращается во встроенную в opengl функцию отсечения.
>>4444
Мне игры делать неинтересно, писал же выше. А оптимизон под веб/мобилки интересно.
96 1014459
>>4445
А в фундаменте капота сидят мультиплеерные кнопки.
97 1014465
>>4458
Увидим ли мы тебя однажды в контрибьюторах годота?
98 1014466
>>4465
Не увидите, я анонимен.
99 1014471
Тем временем вышла вышла вышла новая игра сумрачного финского гения!
100 1014475
>>4471
Чего-то там про круелти сквад? Не интересует как жанр, но видел всплывало повсюду. Удачи ему.
101 1014484
>>4424

>клипуем


>>4458

>вычисления для каждого пикселя


А ты знаешь, как реализован этот клипинг?

Не знаю, попиксельный ли клипинг или нет, но:

>Note: Clipping nodes cannot be nested or placed within CanvasGroups. If an ancestor of this node clips its children or is a CanvasGroup, then this node's clip mode should be set to CLIP_CHILDREN_DISABLED to avoid unexpected behavior.



>оптимизон под веб/мобилки интересно


Возможно, лучше использовать полигон:
https://docs.godotengine.org/en/stable/classes/class_polygon2d.html
И двигать одну из вершин.

Алсо, если тебя интересует оптимизация:
1. Реализуешь каждый вариант по отдельности.
2. Размещаешь десятки тысяч каждого варианта.
3. Собираешь статистику на реальном устройстве.
4. Смотришь, какой вариант тормозит меньше всего.
Всё остальное - бесполезное теоретизирование.

>Мне игры делать неинтересно


Ты симуляцию делать хотел, зачем прогресс-бар?
102 1014487
>>4410

>кодера, который полез нажимать


>>4414

>От преднамеренного поможет только


Ты не понимаешь психологии человеческой.

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

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

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

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

Так и с public/private полями. Да, ты всегда можешь забраться в исходники, заменить private на public и получить доступ к тому, к чему не следует. Но это потребует осознанных усилий, а не обычного кода снаружи класса, что получает доступ к чему-то. Т.е. предупреждение компилятора/интерпретатора о потенциально непреднамеренной ошибке более чем достаточно, чтоб избежать 99% проблем в будущем.

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

Это просто удобнее. В том числе умным людям.
1681944594400.webm13,9 Мб, webm,
854x480, 1:48
103 1014490
>>4484
У меня еще родилась идея сделать шейдер, только не фрагментный, а вершинный - рисовать полигон смещая вершину. Приду с прогулки попробую.

>CanvasGroups


Не пользуюсь пока, да и не помню есть ли в 3-ке.

>Ты симуляцию делать хотел, зачем прогресс-бар?


В смысле зачем? А если мне надо симуляцию с десятками тысяч прогресс баров? Как в CivIdle. Симуляцию сапера 10000х10000 тут уже делали, вроде.

>1. Реализуешь каждый вариант по отдельности.


>2. Размещаешь десятки тысяч каждого варианта.


>3. Собираешь статистику на реальном устройстве.


>4. Смотришь, какой вариант тормозит меньше всего.


>Всё остальное - бесполезное теоретизирование.


Это эксперимент, а эксперимент проверяет теорию. А ее сначала можно построить в голове, на основе знания, то есть представить цепочку как проходят операции, тоже в каком то смысле игра-паззл. Если результат эксперимента не совпадет с теорией, то теория корректируется. А поскольку я занимаюсь оптимизациями по работе много лет, то и ошибаюсь со временем реже. Вот прям практически гарантировано фрагментный шейдер с if- для каждого пикселя медленнее.
104 1014527
>>4490

>фрагментный шейдер


Суть шейдера - нарисовать КРАСИВО. Если нужен переливающийся всеми цветами радуги градиент с интересными волнообразными колебаниями, твои оптимизации сразу идут лесом. И как следствие, потраченное на них время - потрачено впустую. Вот поэтому всегда говорят, что преждевременные оптимизации - корень всех зол, и нужно сначала состряпать рабочую систему/игру из того, что есть.

>эксперимент проверяет теорию


Теория может быть выведена из экспериментов. В геймдизайне ты мало что можешь предсказать теоретическими размышлениями об игроках. А оптимизации должны идти после геймдизайна. Т.е. стряпаешь сырой тормозной прототип, потом, если сработает дизайн, делаешь варианты оптимизации. Нодовая система Godot как раз на это заточена.

>если мне надо симуляцию с десятками тысяч


Тогда ты отображаешь максимум 100 таких баров, остальные скрываются за пределами экрана, ибо отображаются только когда камера приближена. И упрощаешь геометрию баров до прямоугольников. Заменяешь бары на тробберы. Объединяешь сотни отдельных юнитов в группы с одним баром. И т.п. Универсального решения нет, нужно смотреть игру.

>Как в CivIdle


На видео нет баров, там только тробберы:
https://en.wikipedia.org/wiki/Throbber
https://ru.wikipedia.org/wiki/Троббер

>есть ли в 3-ке


А, описанного выше клипинга в тройке вообще нет:
https://docs.godotengine.org/en/stable/classes/class_canvasitem.html#class-canvasitem-property-clip-children
В тройке раньше для этого юзали Light2D:
https://docs.godotengine.org/en/3.6/classes/class_light2d.html
Клипинг прямоугольников, как я понимаю, проще. Поэтому твой способ, в теории, может работать.
https://docs.godotengine.org/en/3.6/classes/class_control.html#class-control-property-rect-clip-content
В актуальной версии переименовали:
https://docs.godotengine.org/en/stable/classes/class_control.html#class-control-property-clip-contents

>вершинный


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

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

У тебя что-нибудь играбельное есть?
Или ты пока делаешь компоненты?
104 1014527
>>4490

>фрагментный шейдер


Суть шейдера - нарисовать КРАСИВО. Если нужен переливающийся всеми цветами радуги градиент с интересными волнообразными колебаниями, твои оптимизации сразу идут лесом. И как следствие, потраченное на них время - потрачено впустую. Вот поэтому всегда говорят, что преждевременные оптимизации - корень всех зол, и нужно сначала состряпать рабочую систему/игру из того, что есть.

>эксперимент проверяет теорию


Теория может быть выведена из экспериментов. В геймдизайне ты мало что можешь предсказать теоретическими размышлениями об игроках. А оптимизации должны идти после геймдизайна. Т.е. стряпаешь сырой тормозной прототип, потом, если сработает дизайн, делаешь варианты оптимизации. Нодовая система Godot как раз на это заточена.

>если мне надо симуляцию с десятками тысяч


Тогда ты отображаешь максимум 100 таких баров, остальные скрываются за пределами экрана, ибо отображаются только когда камера приближена. И упрощаешь геометрию баров до прямоугольников. Заменяешь бары на тробберы. Объединяешь сотни отдельных юнитов в группы с одним баром. И т.п. Универсального решения нет, нужно смотреть игру.

>Как в CivIdle


На видео нет баров, там только тробберы:
https://en.wikipedia.org/wiki/Throbber
https://ru.wikipedia.org/wiki/Троббер

>есть ли в 3-ке


А, описанного выше клипинга в тройке вообще нет:
https://docs.godotengine.org/en/stable/classes/class_canvasitem.html#class-canvasitem-property-clip-children
В тройке раньше для этого юзали Light2D:
https://docs.godotengine.org/en/3.6/classes/class_light2d.html
Клипинг прямоугольников, как я понимаю, проще. Поэтому твой способ, в теории, может работать.
https://docs.godotengine.org/en/3.6/classes/class_control.html#class-control-property-rect-clip-content
В актуальной версии переименовали:
https://docs.godotengine.org/en/stable/classes/class_control.html#class-control-property-clip-contents

>вершинный


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

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

У тебя что-нибудь играбельное есть?
Или ты пока делаешь компоненты?
1671293804368.png45 Кб, 427x347
105 1014539
>>4527

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


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

>А оптимизации должны идти после геймдизайна


А у меня не должны.

>тробберы


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

> упрощаешь геометрию баров до прямоугольников. Заменяешь бары на тробберы. Объединяешь сотни отдельных юнитов в группы с одним баром


А может это преждевременная оптимизация.

>А, описанного выше клипинга в тройке вообще нет:


Так у меня в примере и была 3-йка и рект клиппинг.
Если повернуть родительский объект, то клиппинг работает внутри нового bounding box, возможно этому можно придумать какие то применения для спецэффектов.

>У тебя что-нибудь играбельное есть?


>Геймдизайн, геймдизайн


Сказал же, мне это сейчас неинтересно. Может на Ludum dare сделаю что то за пару дней. Или до ТВГ подожду.
106 1014556
Как можно хранить прогрессию в игре-песочнице? Как из маркера прогресса доставать доступные диалоги и прочее? Пока сделал парочку простых булей для проверок, но это ведь немасштабируемая тема. Сейчас добавляю мясо, и уже не хочется с этими булями работать. А дальше ведь только хуже. Есть получше варианты?
107 1014557
>>4556
Ресурсы. Кастомные ресурсы. Рекомендуемое искаробочное решение.
108 1014558
>>4556
Базы данных.
109 1014559
>>4556
Я просто сохраняю всю сцену в packed scene, дальше загружаю и продолжаю. В рот ебал вручную все восстанавливать.
110 1014560
>>4557
Это про диалоги? Ссылки на внутренние (внутри игры) кастомные ресурсы диалоговой очереди внутри сейва? Или для чего-то еще можно ресурсы уместно в данном контексте применить? Для сохранения прогресса я просто не представляю как их можно использовать. Это ведь те же самые були будут.
>>4559
Не знал, что так можно. А поля автолод классов такой подход затрагивает?
111 1014562
>>4560
Используй силу ООП. Заведи во всех важных классах функции save и load. В save сохраняй только важное геймплейное об объекте. Например позицию, кулдауны итд. А не всякие там состояния анимационного дерева. И каждому объекту выдай уникальный ID, и при сохранении например выбранной врагом цели сохраняй не ссылку на врага, а этот ID. Потом при спавне соответственно функцией load располагаешь все на нужные места, инициализируешь стейтмашины в нужное состояние. Вообще какие то готовые аддоны на это есть, я не пробовал правда.
112 1014586
Самый топ чит, который я нашел, это расписать кучу конкретных разных задач, и делать их под настроение. Сегодня лень кодить? Отлично, вот задача для простенького 3д моделирования, вот для саунда, а вот тут текста не хватает. Как ммо, где под разное настроение идешь в разные локации и делаешь разные активити. Чем выше потенциал к разнообразию, тем ниже шанс что сегодня ты не найдешь интересной для себя активности.

У меня все.
113 1014588
>>4586
Я пошел еще дальше - даже не расписываю ничего. Что нравится, тем и занимаюсь. Правда, игру так и не доделал.
114 1014589
>>4588
Тоже так делал, пока не застрял с сегодня лень выдумывать задачи, нужны готовые
115 1014599
>>4586
У легких задач больший шанс оказаться выполненными, причем быстро. И остаются сложные длинные задачи в которых ты застреваешь, и мозг быстро зарезает весь бюджет допамина выделенный на эту затею. Конец.

Тебе нужно в первую очередь умение деребанить большие задачи на маленкие, и воспринимать их соответственно. Это главный скилл, который появляется с опытом. Чтобы получить этот скилл, нужно просто начать и делать, понимая что ошибки это часть процесса. Одновременно почитывая книжки по сабжу(системное мышление) и консультируясь с нейронкой. Плставив этот скилл на рельсы ты получаешь чит на неограниченный допамин для решения задач любой глубины.
116 1014604
>>4556

>Как можно хранить прогрессию в игре-песочнице?


Если хочешь, чтоб игрок мог редактировать в Блокноте: JSON.
Если хочешь сжато/чтоб игрок не мог править: бинарные файлы.
Если много сложных данных: база данных, как упомянул >>4558

>Как из маркера прогресса доставать доступные диалоги и прочее?


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

1. Есть глобальная последовательность ID (целые числа), которые переключаются друг за другом при достижении игроком определённых триггеров - например, завершение квестов. Это сюжет. Он может быть разветвлённым и нелинейным - главное, чтобы ID были уникальными для каждого этапа/эпизода/главы сюжета. Для простого наглядного примера (без графики и геймплея, чисто сюжет) - посмотри, как создаются и хранятся истории в https://twinery.org/ - его и в более сложных играх используют. "Профессиональные" инструменты отличаются только количеством дополнительных свистелок и тормозами.

2. Глобальная последовательность может делиться на линейки квестов. У каждой линейки квестов есть своя последовательность ID, свои квестодатели, свои условия перехода, свои награды и т.д. Т.е. игрок может проходить параллельно несколько независимых квестовых линеек - в сейве, соответственно, помимо/вместо одного глобального числа-ID будет набор из нескольких чисел. Они могут интегрироваться в глобальный сюжет, если он есть, например, "следующая глава начинается только если игрок завершил N-ное число побочных линеек квестов на текущей локации".

Также есть много плагинов с готовыми решениями - смотри сам, что нравится.

>>4557

>Ресурсы. Кастомные ресурсы.


>>4559

>сохраняю всю сцену в packed scene


Записывать и считывать ресурсы (.tres/.res и .tscn/.scn) на компьютере игрока из произвольного места на диске чревато заражением вирусом в худшем случае (т.к. Godot автоматически выполняет любые загруженные скрипты, а антивирусы эти скрипты никак не распознают, а игроки постоянно обмениваются сейвами; давно уже предлагали сделать песочницу/вырубить скрипты из этих файлов) или просто тяжёлой поломкой сейва в случае неудачного обновления игры (твои скрипты/сцены или какие-то изменения API в новой версии движка), что будет сложно восстановить автоматически и игроку придётся начинать игру с начала. Система ресурсов и сцен удобна только для данных, которые ты экспортируешь в .pck и не пересохраняешь на компе игрока.

Надёжнее хранить все сохраняемые данные в JSON/XML/INI/бинарных файлах/базе данных и заниматься сохранением и восстановлением вручную. Однако, XML избыточно сложный, а INI (ConfigFile) слишком ограниченный. Поэтому либо JSON/бинарные файлы, либо подключать СУБД на свой выбор.

Не надо бояться "ручного" сохранения/загрузки. Там всё легко абстрагируется и управляется.
116 1014604
>>4556

>Как можно хранить прогрессию в игре-песочнице?


Если хочешь, чтоб игрок мог редактировать в Блокноте: JSON.
Если хочешь сжато/чтоб игрок не мог править: бинарные файлы.
Если много сложных данных: база данных, как упомянул >>4558

>Как из маркера прогресса доставать доступные диалоги и прочее?


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

1. Есть глобальная последовательность ID (целые числа), которые переключаются друг за другом при достижении игроком определённых триггеров - например, завершение квестов. Это сюжет. Он может быть разветвлённым и нелинейным - главное, чтобы ID были уникальными для каждого этапа/эпизода/главы сюжета. Для простого наглядного примера (без графики и геймплея, чисто сюжет) - посмотри, как создаются и хранятся истории в https://twinery.org/ - его и в более сложных играх используют. "Профессиональные" инструменты отличаются только количеством дополнительных свистелок и тормозами.

2. Глобальная последовательность может делиться на линейки квестов. У каждой линейки квестов есть своя последовательность ID, свои квестодатели, свои условия перехода, свои награды и т.д. Т.е. игрок может проходить параллельно несколько независимых квестовых линеек - в сейве, соответственно, помимо/вместо одного глобального числа-ID будет набор из нескольких чисел. Они могут интегрироваться в глобальный сюжет, если он есть, например, "следующая глава начинается только если игрок завершил N-ное число побочных линеек квестов на текущей локации".

Также есть много плагинов с готовыми решениями - смотри сам, что нравится.

>>4557

>Ресурсы. Кастомные ресурсы.


>>4559

>сохраняю всю сцену в packed scene


Записывать и считывать ресурсы (.tres/.res и .tscn/.scn) на компьютере игрока из произвольного места на диске чревато заражением вирусом в худшем случае (т.к. Godot автоматически выполняет любые загруженные скрипты, а антивирусы эти скрипты никак не распознают, а игроки постоянно обмениваются сейвами; давно уже предлагали сделать песочницу/вырубить скрипты из этих файлов) или просто тяжёлой поломкой сейва в случае неудачного обновления игры (твои скрипты/сцены или какие-то изменения API в новой версии движка), что будет сложно восстановить автоматически и игроку придётся начинать игру с начала. Система ресурсов и сцен удобна только для данных, которые ты экспортируешь в .pck и не пересохраняешь на компе игрока.

Надёжнее хранить все сохраняемые данные в JSON/XML/INI/бинарных файлах/базе данных и заниматься сохранением и восстановлением вручную. Однако, XML избыточно сложный, а INI (ConfigFile) слишком ограниченный. Поэтому либо JSON/бинарные файлы, либо подключать СУБД на свой выбор.

Не надо бояться "ручного" сохранения/загрузки. Там всё легко абстрагируется и управляется.
bank.png8 Кб, 380x450
117 1014609
>>4556 >>4604
Приведу пример, как это можно оформить в коде.

Допустим, есть три+ главы сюжета и квест "ограбление банка":

>bank.tscn / bank.gd


># save_data может быть локальным для этого экземпляра банка


>func load_state(save_data: SaveData) -> void:


>_ match save_data["story"].phase:


>_ _ 1: # первая глава: банк в норме (сюжет о чём-то другом идёт)


>_ _ _ spawn_default_state() # банк - всего лишь декорация


>_ _ 2: # вторая глава: игрок обнаружил, что банк грабят


>_ _ _ match save_data["bank"].phase:


>_ _ _ _ 1: spawn_bandits() # игрок поблизости - начато ограбление


>_ _ _ _ 2: spawn_cops(false) # приехали копы, игрок их не трогал


>_ _ _ _ 3: spawn_cops(true) # приехали копы, игрок в них пострелял


>_ _ 3: # третья глава: после ограбления


>_ _ _ match save_data["bank"].phase:


>_ _ _ _ 4: spawn_robbed_state() # банк ограблен и закрыт (3 -> 4)


>_ _ _ _ 5: spawn_with_cute_maid() # в банк ходит горничная (2 -> 5)


>_ _ _ _ 6: spawn_default_state() # игрок нанял горничную (5 -> 6)


>_ _ _: # все остальные главы после третьей


>_ _ _ spawn_default_state() # банк восстановлен или горничная ушла


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

В больших ААА-играх плюс-минус такая же система используется...
118 1014620
>>4604

>Записывать и считывать ресурсы (.tres/.res и .tscn/.scn) на компьютере игрока из произвольного места на диске чревато заражением вирусом в худшем случае


>а игроки постоянно обмениваются сейвами


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

Аргумент с поломкой сейва актуален и для классических сейвов в JSON/XML/whatever. Знаем мы эти истории, когда разработчикам приходилось городить целую цепочку конверторов сейвов, от игры версии 1 до игры версии 9000, и все равно оно ломалось. А потом в чейнджлогах ААА игорь видишь "для фичи Х придется начать новую игру".

А у меня буквально 3 строки кода и идеально полное сохранение/загрузка всего.
119 1014621
>>4620

>мне пофиг на людей, которые качают рандомное дерьмо из интернета


Вот только претензия "не качайте там вирус" будет прилетать именно к твоей игре.
120 1014623
>>4621
Шизы любят раскидываться такими заявлениями. Одна моя игра вообще без сейвов получала такой отзыв. Поглядываю за бывшим мейнтейнером годота, Юрой Сизовым, он со своим саунд-редактором тоже подобного огреб, ныл потом в соцсетях. Конкретно в моей игре вирусов нет, а чего там пользователь понакачал хуй пойми откуда - меня не касается, я ему не мамка. В точности как вирусы в крякнутых ААА торрентах не касаются разработчиков ААА игр.
121 1014625
>>4621
И если уж на то пошло, то модами обмениваются чаще чем сейвами, и говна туда напихать легче. Не вижу чтобы за вирусный мод прилетало разработчику игры.
122 1014638
Внезапно!
Туториал на немецком.
https://www.youtube.com/watch?v=gwsAIawjMwE
Впрочем, 21 век, будущее наступило, ИИ переводит с немецкого и озвучивает.
123 1014647
>>4625

>модами обмениваются


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

TL;DR:
- вирус в ожидаемом месте - ладно
- вирус в неожиданном месте - пипец
124 1014650
>>4638
Шизик /gd перешёл на годот?
125 1014656
>>4647
Сейвы тоже качают на свой страх и риск. Причем в разы меньше чем моды. Он вот знает, когда качает, что это реально сейв-файл, а не говно под видом сейва? Ничего он не знает. Тем более если речь о нормисах, они вообще не ебут что где-то какие-то сейвы хранятся и ими можно обменяться.

Короче я думаю это надуманная проблема и твердо намерен релизнуть как есть. Если вылезут непредвиденные последствия - обязательно приду рассказать ИТТ.
126 1014662
>>4620

>Аргумент с поломкой сейва актуален


Нет, ты не понимаешь сути проблемы.

В случае ресурсов:
1. Ты создал поле mob_amount.
2. Игрок сохранил игру в версии 0.1.
3. Ты переименовал mob_amount -> mob_count.
4. Игрок загружает сохранение в версии 0.2.
5. Godot БЕЗ ПРЕДУПРЕЖДЕНИЯ устанавливает в mob_count значение по умолчанию, а mob_amount игнорирует, и оно утратится после сохранения. В зависимости от предназначения поля, игровые последствия утраты могут быть от незаметных до полностью ломающих геймплей. Хуже всего, когда геймплей полностью ломается, но незаметно...
Godot даже в редакторе об этом никак не может предупредить и помочь сохранить утраченное; в результате приходится придумывать костыли, но в рантайме эти костыли будут намного сложнее.

В случае сцен:
1. Ты создал digger с нодой shovel.
2. Игрок сохранил игру в версии 0.1.
3. Ты поменял ноду shovel на pickaxe.
4. Игрок загрузил игру в версии 0.2.
5. Godot БЕЗ ПРЕДУПРЕЖДЕНИЯ ломается, т.к. не способен найти удалённую сцену shovel и даже не пытается добавить персонажу в руки pickaxe. В лучшем случае это будет мелкая проблема - чувак будет с пустыми руками бегать. В худшем случае игрок проиграет +50 часов и ВНЕЗАПНО обнаружит, что отсутствие кирки, необходимой для продвижения по сюжету, фиксится только началом игры с нуля.
В редакторе Godot иногда предупреждает о таких проблемах, но в рантайме такие проблемы будет значительно сложнее пофиксить автоматически. Текущая версия системы UID тут не помогает.

>городить целую цепочку конверторов сейвов


Во-первых, с кастомным форматом ты ИМЕЕШЬ ВОЗМОЖНОСТЬ написать эту цепочку конвертеров. Стандартные ресурсы в Godot ломаются часто и без предупреждения, формат записи у них сложный и встроенные инструменты конвертации недоступны. Задолбаешься парсить tres вручную в обход Godot.

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

>А у меня буквально 3 строки кода


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

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

>рандомное дерьмо из интернета.



Сразу отвечу на следующие аргументы:

>просто не меняй поля в tres


>просто не меняй ноды в tscn


>просто не обновляй аддоны


>просто не обновляй Godot


>просто не обновляй игру


Ответ: если твоя игра позволяет ничего в себе не обновлять, то ты флипнул ассеты за вечер и теперь называешь это игрой. Представь себе, некоторые игровые проекты обновляются более 25 лет, и они вынуждены вносить существенные изменения. Большинство поделок, конечно, так долго не живут, однако не путайте причину со следствием - если вы наговнокодили, разумеется, обновлять будет очень больно, даже если игра вдруг станет популярной, и множество проектов сдохли из-за говнокода (или потеряли в популярности/проиграли конкурентам).
126 1014662
>>4620

>Аргумент с поломкой сейва актуален


Нет, ты не понимаешь сути проблемы.

В случае ресурсов:
1. Ты создал поле mob_amount.
2. Игрок сохранил игру в версии 0.1.
3. Ты переименовал mob_amount -> mob_count.
4. Игрок загружает сохранение в версии 0.2.
5. Godot БЕЗ ПРЕДУПРЕЖДЕНИЯ устанавливает в mob_count значение по умолчанию, а mob_amount игнорирует, и оно утратится после сохранения. В зависимости от предназначения поля, игровые последствия утраты могут быть от незаметных до полностью ломающих геймплей. Хуже всего, когда геймплей полностью ломается, но незаметно...
Godot даже в редакторе об этом никак не может предупредить и помочь сохранить утраченное; в результате приходится придумывать костыли, но в рантайме эти костыли будут намного сложнее.

В случае сцен:
1. Ты создал digger с нодой shovel.
2. Игрок сохранил игру в версии 0.1.
3. Ты поменял ноду shovel на pickaxe.
4. Игрок загрузил игру в версии 0.2.
5. Godot БЕЗ ПРЕДУПРЕЖДЕНИЯ ломается, т.к. не способен найти удалённую сцену shovel и даже не пытается добавить персонажу в руки pickaxe. В лучшем случае это будет мелкая проблема - чувак будет с пустыми руками бегать. В худшем случае игрок проиграет +50 часов и ВНЕЗАПНО обнаружит, что отсутствие кирки, необходимой для продвижения по сюжету, фиксится только началом игры с нуля.
В редакторе Godot иногда предупреждает о таких проблемах, но в рантайме такие проблемы будет значительно сложнее пофиксить автоматически. Текущая версия системы UID тут не помогает.

>городить целую цепочку конверторов сейвов


Во-первых, с кастомным форматом ты ИМЕЕШЬ ВОЗМОЖНОСТЬ написать эту цепочку конвертеров. Стандартные ресурсы в Godot ломаются часто и без предупреждения, формат записи у них сложный и встроенные инструменты конвертации недоступны. Задолбаешься парсить tres вручную в обход Godot.

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

>А у меня буквально 3 строки кода


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

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

>рандомное дерьмо из интернета.



Сразу отвечу на следующие аргументы:

>просто не меняй поля в tres


>просто не меняй ноды в tscn


>просто не обновляй аддоны


>просто не обновляй Godot


>просто не обновляй игру


Ответ: если твоя игра позволяет ничего в себе не обновлять, то ты флипнул ассеты за вечер и теперь называешь это игрой. Представь себе, некоторые игровые проекты обновляются более 25 лет, и они вынуждены вносить существенные изменения. Большинство поделок, конечно, так долго не живут, однако не путайте причину со следствием - если вы наговнокодили, разумеется, обновлять будет очень больно, даже если игра вдруг станет популярной, и множество проектов сдохли из-за говнокода (или потеряли в популярности/проиграли конкурентам).
127 1014666
>>4662
Решение есть, просто не переименовывай, а помечай deprecated и добавляй новое поле.
128 1014668
>>4662
Давай тут без своих корявых гаданий на кофейной гуще. Ассеты все делаю сам в 3д редакторе, 2д арт тоже, игра в разработке больше года. Решение для обновления старых .scn-сейвов на новые написано. Остальные твои аргументы меня не ебут, потому что они из разряда "а что если васян с крыши упадет, ты виноват ведь ты дом построил!11".
129 1014693
>>4662
А я двачую этот пост. Всегда был сторонником кастомного формата. Как правило жсон.
130 1014699
>>4604
>>4609
Большое спасибо! Особенно за пример. Я такую систему уже успел выдумать сам, только постеснялся здесь писать. Думал, что глупости совсем. Можно еще эти фазы оформлять как инт из битфлага, например, чтоб это не были числа из головы. Там, где это уместно, разумеется.

>чревато заражением вирусом


Годонирс, кажется, выпускал аддон, который пробегается по сейву и отменяет его чтение как ресурса, если в нем есть скриптовая часть. Но я тебя понял. На json формат перейду наверное, с tscn я уже намучился.
Эмбеддил кастомный ресурс в заэмбеженный кастомный ресурс внутрь кастомного ресурса сейва, каюсь.
131 1014704
>>4656

>Если вылезут непредвиденные последствия - обязательно приду рассказать ИТТ.


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

Но вообще, сохранение состояния в словарь, а из него в жсон - это очень просто, хотя бы в следующем проекте крайне рекомендую освоить данную технологию. Она тебе в будущем пригодится там, где ты сейчас даже и предположить не можешь. Вот тебе пример из жизни. Я щас пишу софтину на плюсах (годот отложил пока) и написал сохранение в жсон. Использую библиотеку, с которой работа с жсон-объектом не отличается от работы с вложенными словарями в годоте. Так вот, когда дошло до написания гуя, я сначала очень расстроился, что слишком геморно для этого использовать Годот, как изначально планировалось, я обнаружил, что самый практичный способ общения между основой и гуём - это те самые жсон-объекты, которые я планировал использовать только для сохранения в файл.
И вообще, помни: разрабатывая игру, ты получаешь навыки и знания, которые пригодятя в самых разных прочих областях разработки.
0.png86 Кб, 730x940
132 1014705
>>4668

>Решение для обновления старых .scn-сейвов на новые


Поделись же им с нами, раз ты так сильно рекомендуешь этот чудесный способ.

>а что если васян с крыши упадет, ты виноват ведь ты дом построил


Виноват, если ты сделал слабую крышу, что обвалилась под васяном, который эту крышу после тебя доделывал, или даже над васяном, который просто мимо стройки проходил. Нормальные строители ГОСТы соблюдают, а ещё есть УК РФ 216: "Нарушение правил безопасности при ведении строительных или иных работ". Будешь спорить и доказывать, что васян всё ещё сам виноват, что проходил мимо, когда твоя крыша обвалилась ему на голову?

К счастью, ты не строитель и крыши не строишь, поэтому твоя поделка на чью-то голову не упадёт. Но рекомендую ознакомиться с УК РФ 273: "Создание, использование и распространение вредоносных компьютерных программ". Оправдываться, что ты не знал об уязвимости и не пытался намеренно совершать сделанное, будешь уже перед другими людьми...
133 1014709
>>4704

>Но вообще, сохранение состояния в словарь, а из него в жсон - это очень просто,


Покажешь? Для годота.
134 1014713
>>4704

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


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

>>4705
Какой ты унылый бюрократ. ГОСТ на обкладывание соломой еще принеси, и пригрози УК всем кто делает иначе.
135 1014720
>>4713

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


Главное - не тащить структуру проекта в сейв. Отношение к сейву должно быть как к таблице базы данных. И ЖСОН позволяет сделать структуру как таблица. Вот есть такой сайт жсон-редактор-онлайн. Так вот там есть возможность представить особым образом составленный жсон как таблицу. В чём состоит эта особость? В жсоне должен быть один или больше массив [] однотипных объектов {}, ключи из этих объектов становятся именами столбцов виртуальной таблицы, значения - значениями строк.

Необязательно юзать редакторы, но вышеприведённый редактор позволяет постигнуть эту идею.
136 1014723
>>4720
Проще скринами показать. Допустим есть такой жсон (пикча1) включаем режим, выбираем таблицу и редактируем. А в движке соответственно делаем несложный код, который находит в файле таблицы и читает их последовательно, извлекая данные и определяя их по полю наподобие "type". Таким подходом частично решается и немного упрощается вышеописанная проблема смены формата. Ты не добавляешь в сейв произвольные данные, ты добавляешь структурированные данные, у которых есть тип, подтип, имя, значение, иные параметры. И когда ты начнёшь мыслить в этой парадигме (парадигме СУБД) тебе будет сложнее "случайно" вносить ломающие изменения в свои же форматы.
1742922001456.png35 Кб, 378x618
137 1014726
>>4723
Обычно вот такие жсоны пихают в сейв, а потом жалуются, что их масштабировать сложно. Здесь только инвентарь в виде таблицы, остальное прибито гвоздями к внутренней реализации.
138 1014732
>>4709
Сохраняем:
func to_dict() -> Dictionary:
. var dict = {
. . foo = foo, # int
. . bar = bar, # String
. . obj = obj.to_dict();
. . connections = {
. . . connected_node1.name, connected_node2.name
. . }
. }
. return dict
Загружаем:
func from_dict(dict: Dictionary)
. if dict.has("foo") and dict.foo is int: foo = dict.foo
. if dict.has("bar") and dict.bar is String: bar = dict.bar
. if dict.has("obj") and dict.obj is Dictionary:
. . obj = new Obj
. . obj.from_dict(dict.obj)
После восстановления всех нод восстанавливаем соединения
func connections_from_dict(dict: Dictionary)
. if not dict.has("connections") or not (dict.connections is Array): return
. for connection in dict.connections:
. . conn: Node = get_node(connection)
. . if is_instance_valid(node): restore_connection_with(node)

Всё. и так можно сохранить проект ЛЮБОЙ сложности.

>>4713

>Чем комплексней структура проекта, чем больше взаимосвязей между объектами


Вообще, это огромный редфлаг, обозначающий, что пора бы заняться рефакторингом. Энивей, см.выше.
138 1014732
>>4709
Сохраняем:
func to_dict() -> Dictionary:
. var dict = {
. . foo = foo, # int
. . bar = bar, # String
. . obj = obj.to_dict();
. . connections = {
. . . connected_node1.name, connected_node2.name
. . }
. }
. return dict
Загружаем:
func from_dict(dict: Dictionary)
. if dict.has("foo") and dict.foo is int: foo = dict.foo
. if dict.has("bar") and dict.bar is String: bar = dict.bar
. if dict.has("obj") and dict.obj is Dictionary:
. . obj = new Obj
. . obj.from_dict(dict.obj)
После восстановления всех нод восстанавливаем соединения
func connections_from_dict(dict: Dictionary)
. if not dict.has("connections") or not (dict.connections is Array): return
. for connection in dict.connections:
. . conn: Node = get_node(connection)
. . if is_instance_valid(node): restore_connection_with(node)

Всё. и так можно сохранить проект ЛЮБОЙ сложности.

>>4713

>Чем комплексней структура проекта, чем больше взаимосвязей между объектами


Вообще, это огромный редфлаг, обозначающий, что пора бы заняться рефакторингом. Энивей, см.выше.
139 1014734
>>4732
Интересно. А как ты, например, сохраняешь текущую анимацию, ее скорость, направление и позицию?
140 1014738
>>4732

> if dict.has("foo") and dict.foo is int: foo


Вот эту хрень надо выносить в метод. Что-то типа

> func _cast_to_type(dict: Dictionary, key: String, type: int, default: Variant) -> Variant:


> > if dict.has(key) and type_of(dict[key]) == type:


> > > return dict[key]


> > return default


Ну и после этого уже элегантнее будет:

> foo = _cast_to_type(dict, "foo", TYPE_INT, foo)


> bar = _cast_to_type(dict, "bar", TYPE_STRING, bar)

141 1014739
>>4738
Эх, в шарпе такие штуки ещё элегантнее пишутся, там caller member name выводится.
142 1014740
>>4720 >>4723 >>4726
Я всё внимательно прочитал и попробовал этот онлайн-редактор, но не понял, как ты это предлагаешь использовать, если у тебя в проекте больше одного экземпляра объекта. И зачем нужны дублирующиеся поля? Ты собираешься это вручную читать? Если ты предлагаешь создавать SQL запросы к этому сейву, не проще ли будет сразу подключить СУБД к проекту, а не делать велосипед с квадратными колёсами (JSON)? Я не понимаю, чем твой способ будет лучше.

Твой способ, как я его понимаю:

>location.gd


>func load(data): # получаем все данные, ибо хрен разберёшь


>_ for line in data.world_data:


>_ _ if line.type == "location":


>_ _ _ match line.name:


>_ _ _ _ "name": name = line.value


>_ _ _ _ "state": state = line.value


>_ _ _ _ "weather": weather = line.value


>_ _ _ _ "time": time = line.value


Очень странно. Это будет долго и неэффективно.
Возможно, через SQL будет быстрее и эффективнее?..

Нормальный способ, который тебе чем-то не нравится (чем?):

>location.gd


>func load(data): # получаем кусочек данных от заботливого родителя


>_ name = data.name


>_ state = data.state


>_ weather = data.weather


>_ time = data.time


Легко и понятно. Никакого "прибивания гвоздями" (где?) тут нет.

Если у тебя изменится первый вариант:

>_ _ _ _ "state": status = line.value


Если у тебя изменится второй вариант:

>_ status = data.state


Как видишь, разницы в обратной совместимости нет.

>>4732

>if dict.has("foo") and dict.foo is int: foo = dict.foo


Проще так записать:

>foo = dict.get("foo", foo)


А если у тебя там тип неправильный, то всё уже сломалось.

>if not dict.has("connections") or not (dict.connections is Array):


Можно так записать:

>if "connections" not in dict or dict.connections is not Array:



>>4734

>сохраняешь текущую анимацию


О какой анимации речь? И нужно ли её вообще сохранять?
Сохраняй только то, что нельзя восстановить при загрузке.
142 1014740
>>4720 >>4723 >>4726
Я всё внимательно прочитал и попробовал этот онлайн-редактор, но не понял, как ты это предлагаешь использовать, если у тебя в проекте больше одного экземпляра объекта. И зачем нужны дублирующиеся поля? Ты собираешься это вручную читать? Если ты предлагаешь создавать SQL запросы к этому сейву, не проще ли будет сразу подключить СУБД к проекту, а не делать велосипед с квадратными колёсами (JSON)? Я не понимаю, чем твой способ будет лучше.

Твой способ, как я его понимаю:

>location.gd


>func load(data): # получаем все данные, ибо хрен разберёшь


>_ for line in data.world_data:


>_ _ if line.type == "location":


>_ _ _ match line.name:


>_ _ _ _ "name": name = line.value


>_ _ _ _ "state": state = line.value


>_ _ _ _ "weather": weather = line.value


>_ _ _ _ "time": time = line.value


Очень странно. Это будет долго и неэффективно.
Возможно, через SQL будет быстрее и эффективнее?..

Нормальный способ, который тебе чем-то не нравится (чем?):

>location.gd


>func load(data): # получаем кусочек данных от заботливого родителя


>_ name = data.name


>_ state = data.state


>_ weather = data.weather


>_ time = data.time


Легко и понятно. Никакого "прибивания гвоздями" (где?) тут нет.

Если у тебя изменится первый вариант:

>_ _ _ _ "state": status = line.value


Если у тебя изменится второй вариант:

>_ status = data.state


Как видишь, разницы в обратной совместимости нет.

>>4732

>if dict.has("foo") and dict.foo is int: foo = dict.foo


Проще так записать:

>foo = dict.get("foo", foo)


А если у тебя там тип неправильный, то всё уже сломалось.

>if not dict.has("connections") or not (dict.connections is Array):


Можно так записать:

>if "connections" not in dict or dict.connections is not Array:



>>4734

>сохраняешь текущую анимацию


О какой анимации речь? И нужно ли её вообще сохранять?
Сохраняй только то, что нельзя восстановить при загрузке.
143 1014741
>>4740

>О какой анимации речь?


У меня animation player и долгая анимация в нем. Иногда я ее запускаю задним ходом через play_backwards
144 1014742
>>4740

> Возможно, через SQL будет быстрее и эффективнее?



Да пожалуй, лучше сразу через мускль.
145 1014743
>>4742
А сверху мускуля обязательно прослойку с ORM, на случай если базу на полпути сменить придется.
146 1014744
>>4743
И мультиплеерные кнопки непременно.
1742927898535.png109 Кб, 911x611
147 1014745
Скулять.
148 1014746
>>4741

>долгая анимация в нем


Что за анимация-то?

Основные варианты:
1. Кат-сцена. Сохраняешься ПЕРЕД кат-сценой, а не во время.
2. Действие персонажа. Сохраняешься перед/после действия.
3. Состояние персонажа. Запускаешь анимацию с нуля/с конца.

В любом случае, анимации - обычно декорации, а не геймплей.

Что плохого в том, что декорации "неправильно" загрузятся?
149 1014748
>>4746
То есть твой подход, который:

>и так можно сохранить проект ЛЮБОЙ сложности.


Разваливается как только я делаю шаг в сторону от банального менеджера инвентаря, и начинаются костыли-подпорки либо "нинужно". Представляю что будет если я захочу сохраниться во время скриптованной на твинах интерактивной нелинейной сцены, или если у меня физическая симуляция с _integrate_forces, или процедурное создание материалов, или ...
150 1014749
>>4748
А каков твой подход?
151 1014751
>>4749
Страдать. Я не нашел универсального и удобного способа или готового решения, способного безболезненно сохранить любое состояние любой ноды/объекта/сцены/скрипта/анимации/диалога/физики/звука. Чем более нестандартный проект тем хуже. Поэтому всегда охуеваю с ваших советов уровня "просто используй жысон/ресурсы/sql", когда совсем не в них дело.

В этом плане приятно мобильные дрочильни делать, где ты сохраняешь int пройденных уровней и больше ничего.
152 1014755
>>4751
Не ты один страдаешь. Заметил, что в подавляющем большинстве современных игор сохранения специально установленными чекпоинтами? То-то же. Игра набита под завязку рандомно генерирующимися эффектами постобработки и сохранить всё это барахло дороже, чем. Чем.

Алсо для анимационного плеера:

> current_animation


> current_animation_length


> current_animation_position


Сохраняй на здоровье.
Со звуком и физикой так же.

Просто ты заебёшься всё сохранять, а игроки этих трудов не оценят и будут обсирать тебя на форумах, что когда они траят босса, приходится по несколько минут ждать загрузки.
153 1014756
>>4740

>Проще так записать


>Можно так записать


Не душни, суть-то не в этом

>>4734

>А как ты, например, сохраняешь текущую анимацию, ее скорость, направление и позицию?


dict = {
...
. anim_name = animation_player.assigned_animtion,
. anim_speed = animation_player.get_playing_speed(),
. anim_pos = animation_player.current_animation_position
...
}
Но, во-первых, нахуя, а во-вторых упаковкой сцены ты вроде эти вещи даже и не сохранишь.
>>4748

>скриптованной на твинах интерактивной нелинейной сцены, или


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

>физическая симуляция


Симулируется заново; параметры симуляции пишутся в словарь.

>процедурное создание


Сид пишется в словарь, и у тебя всё воссоздастся точно так же.

Ах да, ну и да, у меня случился эффект манделы, и я забыл, что встроенной функции преобразования словаря в жсон нету. Зато можно сделать var_to_str(dict) и получить сериализованный словарь, очень похожий на жсон. Ну и обратное str_to_var тоже работает.

Анимация действительно тут самое сложное; но если у тебя в игре присутствует прям реально длинная сложная анимация, которая ещё и влияет на геймплей, которую ещё и надо сохранять-загружать - значит где-то ты свернул не туда. Такие штуки - это бомбы замедленного действия, лучше сразу проектировать без них, чем на поздней стадии разработки понять, что теперь придётся всё переделывать.
154 1014758
>>4755
Для аудиострима get_playback_position
И далее и далее по мере поступления.
155 1014759
>>4756

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


Я не он, но я помню шутеры 90х-2000х, когда сохраняешься с летящей в полёте пулей, а при загрузке пуля тебя застреливает. Это раздражало, но это была фича.
156 1014763
>>4756

>Симулируется заново;


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

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


Снова, чуть в сторону от менеджера инвентаря и все разваливается и слышь переделывай.

Сейвы, по сути, каждый раз одно и то же простое действие - запиши-прочитай - но каждый сука раз оно достаточно разное чтобы прыгать с бубном и тратить время на унылые обвязки-бойлерплейты. А напишут ли мне в отзывах что у меня охуенные сейвы? Нет, всем похуй, ведь это базовый функционал, а ты каждый раз ебись с ним. А мог бы потратить это время на что-то интересное.
157 1014800
>>4763

> Физика не детерминирована, даже с Jolt'ом


В рамках одной платформы всё воспроизводимо, как раз таки с джолтом
https://github.com/godot-jolt/godot-jolt/discussions/548?ysclid=m8penlk9ee155947311
158 1014812
>>4759

>я помню шутеры 90х-2000х, когда сохраняешься с летящей в полёте пулей, а при загрузке пуля тебя застреливает


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

>>4763

>Физика не детерминирована


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

>Сейвы, по сути,


Ну тут да. Не помню, у кого из блогеров видел этот тезис (наверняка у GMTK), мол, в разработке игр есть fun part, когда ты делаешь непосредственно игру, а есть огромная куча всего, что сделать всё равно необходимо, но это скучная рутина, которую игрок даже не заметит. И это касается не только сейвов, это ещё настройки, логика работы гуя, всякие там стейт-машины и куча другого.
Ну, c'est la vie, чо.
159 1014844
>>4748

>костыли-подпорки либо "нинужно"


Да, не нужно. Ты вообще в игры играешь? Ты часто замечаешь, в каком состоянии загружается игра? В каком состоянии находятся все анимации, физика? Большинство игроков невнимательны к деталям. Загрузка игры должна восстановить всё, что может потребоваться для прохождения игры на 100% - всё остальное может быть в произвольном состоянии.

>Представляю что будет если я захочу сохраниться во время скриптованной на твинах интерактивной нелинейной сцены, или если у меня физическая симуляция с _integrate_forces, или процедурное создание материалов, или ...


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

>>4756

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


Кто тебе такой бред сказал? Всё есть и работает:
https://docs.godotengine.org/en/stable/classes/class_json.html#class-json-method-stringify
https://docs.godotengine.org/en/3.6/classes/class_json.html#class-json-method-print

>>4763

>>Симулируется заново;


>Физика не детерминирована


Главное, чтоб объекты не проваливались в пол.

>может ты физический паззл делаешь


Вот когда ты его сделаешь - тогда и поговорим.

>сиди теперь пару минут жди чтобы вернуться


В чём проблема подождать всего лишь 2 минуты?

>все разваливается и слышь переделывай


Это и есть разработка программного обеспечения.

>унылые обвязки-бойлерплейты


А ты делай весёлые обвязки.
160 1014846
>>4812

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


ГУЙ хотя бы стилизовать можно по-новому, а над UX интересно работать. Сейвы же просто подкапотная муть, которую никто не увидит.

>>4844

>не нужно


>не нужно


>не нужно яскозал


Не нужен тут только твой бесполезный коммент, сорян.
161 1014847
>>4844

> Кто тебе такой бред сказал? Всё есть и работает:


Я кстати не в первый раз вижу длиннопосты с подобными воззрениями на движок. Складывается ощущение, что какой-то хуй, ни разу не открывавший годот, залез в тред и жирно набрасывает движкосрача на вентилятор.
>>4812

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


> Ну, c'est la vie, чо.


Нужно поглядывать в ассетлиб, может оказаться, что множество бойлерплейтовых работ уже произведено, только скачивай да используй.
Вот, например, менеджер сохранений https://godotengine.org/asset-library/asset/3765 вряд ли присутствующие в треде напишут толковее (я проверил код).
162 1014849
>>4846

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


Если сохраняешь в JSON, игроки могут залезть в сохранение и подправить значения руками. Может существенно упростить работу моддерам. Может упростить жизнь желающим "читерить" в сингле. Теоретически упрощает фикс багов игры игроком (например, когда важная вещь тупо деспавнулась).

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

>>не нужно яскозал


>Не нужен тут только твой


А что НУЖНОГО делаешь ты?

Опиши, что тебе не удаётся сейчас сохранить.
Покажи на видео, как оно сейчас загружается.
Покажи на видео, как оно должно загружаться.
Подумаем вместе, как решить твою проблему.
163 1014857
>>4847

>менеджер сохранений


Какой-то бредовый плагин...

>In order to be able to manipulate those StorageAccessors, an autoload called GlobalStorageManager is defined when the plugin is activated. This is a singleton capable of collecting and sending data to all active StorageAccessors in the scene.


Что он предлагает? Насрать нодами в дерево? Так?

>игрок: CharacterBody3D


>_ сохранятор_игрока: StorageAccessor


>_ пистолет: Пуляло3D


>_ _ сохранятор_пистолета: StorageAccessor


>_ _ магазин: Node3D


>_ _ _ сохранятор_магазина: StorageAccessor


>_ портки: Портки3D


>_ _ сохранятор_портков: StorageAccessor


>_ _ шнурки: Шнурок3D


>_ _ _ сохранятор_шнурков: StorageAccessor


И, конечно, это всё обмазано синглтоном.
164 1014861
>>4849

>В любом случае, некоторые игроки спасибо скажут.


Сколько тебе сказали спасибо за жсонные сохранения? Покажи на видео, где тебе говорят спасибо. Мне за мои предыдущие игры никто не сказал, сохранял в жсон, за сотни отзывов ноль про сейвы. Мне кажется править сейвы руками это еще более редкое чем обмен сейвами. В общем, все это - надуманные причины, чтобы страдать при каждой реализации сейвов. А от надуманных причин надо избавляться.
165 1014870
Ну я ж говорю, он тут траллит. Вот, взгляните: >>4857
166 1014874
Кстати, я когда оптимизировал игру под веб/яи, вспомнил еще один минус синглтонов. Все автолоады то грузятся сразу. А надо чтобы сначала загрузился только легковесный стартовый экран. Плюс захват мыши и аудио в вебе должны включаться только после первого клика пользователя мышкой. А в плагинах то все любят пихать все в автолоады и включать сразу на старте, что просто отваливается.
167 1014875
Это коммент к

>In order to be able to manipulate those StorageAccessors, an autoload called GlobalStorageManager is defined when the plugin is activated.


Так что да, тот анон прав, это в каком то смысле "насрать"
168 1014877
>>4861

>причины, чтобы страдать


https://ru.wikipedia.org/wiki/Технический_долг

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



Вообще, я не понимаю, в чём твои "страдания"...
Какая у тебя скорость? Хотя бы 100 слов в минуту?

>>4870
Френдли фаер, ты не туда воюешь.

>>4875
Речь о том, что StorageAccessor автор этого аддона предлагает пихать везде, где нужно что-то хранить и загружать. Хрен с ним, с синглтоном - почему вместо

>MyAwesomeStorageSingletonAddon.save(id, data)


>data = MyAwesomeStorageSingletonAddon.load(id)


Автор предлагает пихать тыщи новых нод в дерево?
169 1014890
>>4877
Годот нодовый движок. Ноды используют аля компоненты. Может там есть настройка мышкой что сохранять из сцены, еще не смотрел.

>>4847

> (я проверил код).


Проверь получше, такое оформление в наши дни делает нейронка, возможно и код весь написан нейронкой.
170 1014897
>>4890

>Годот нодовый движок.


Да, но нодами не рекомендуется срать.
https://docs.godotengine.org/en/stable/tutorials/best_practices/node_alternatives.html

>Nodes are cheap to produce, but even they have their limits. A project may have tens of thousands of nodes all doing things. The more complex their behavior though, the larger the strain each one adds to a project's performance.


>Godot provides more lightweight objects for creating APIs which nodes use. Be sure to keep these in mind as options when designing how you wish to build your project's features.


И ещё есть эта статья, но немного про другое.
https://docs.godotengine.org/en/stable/tutorials/performance/using_servers.html

>Ноды используют аля компоненты.


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

Проблема такой системы сохранения в том, что ты размазываешь игровой объект на несколько нод, совершенно без какой-либо практической пользы.
171 1014904
>>4897
Смысл в том, что ты вообще не пишешь ни строчки кода (не создавая зависимость внутри .gd), а только вешаешь ноду на те объекты которые хочешь сохранять.
Аналогия - создавать MeshInstance нодами или создавать их из кода. Иногда удобнее так, иногда так.
image.png173 Кб, 390x280
172 1014910

> surface_set_material()


> set_surface_material()

Стикер480x512
173 1014913
>>4910

>test1()

1608626265607.jpg133 Кб, 928x486
174 1014920
>>4910
И че? Там именно такой разный смысл.
image.png976 Кб, 917x707
175 1014923
>>4920
material_surface_set
176 1014934
В лагерь любителей использовать ресурсы для сохранения.
Есть два любопытных класса: ResourceFormatSaver и ResourceFormatLoader
От них наследуешься и реализуешь свой собственный формат файла.
Я днём попробовал - работает. Код не покажу, ибо на другой машине. Документация в помощь, там несложно.

Могу только сказать, у меня получилось формировать файл .save с ini-форматированием внутри. А потом я еще по другому закодил и получилось бинарное содержимое внутри.
177 1014940
>>4904

>не создавая зависимость внутри .gd


Выше уже кидали код, который не создаёт зависимостей:

>func load(data: Dictionary): ...


>func save() -> Dictionary: return { ... }


Не нужно тут никаких дополнительных нод и синглтонов.

Просто всё происходит по иерархии:

>A # сохраняет/загружает B, пишет/читает в/из файл/а


>_ B # сохраняет/загружает C


>_ _ C # сохраняет/загружает D


>_ _ _ D # лист дерева сцены



Поток данных во время сохранения:

>файл <- A <- B <- C <- D


Поток данных во время загрузки:

>файл -> A -> B -> C -> D



Аргументируй, если считаешь это неправильным.
178 1014943
>>4934

>ResourceFormatSaver и ResourceFormatLoader


>получилось формировать файл .save


Эти классы нужны только для интеграции с инспектором в редакторе сцен:

>Godot loads resources in the editor or in exported games using ResourceFormatLoaders.


Планируешь открывать свои .save-файлы в редакторе (как .tres)? Нет? Тогда зачем?
179 1014945
>>4934
Основная проблема с сохранениями/загрузками не в том, какой формат использовать, а в том, что ты каждый раз бегаешь как охуевший по всей своей кодовой базе и выискиваешь какие значения у каких объектов нужно сохранить и как их потом восстановить. А куда сохранять - похуй вообще, хоть на забор записывай. Вы вообще не туда спорите, не улавливаете сути проблемы.
180 1014950
>>4945

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


Разве? Для примера, у тебя есть: персонаж, автомобиль, квартал города, город.

Что должен сохранять/загружать персонаж? Это персонаж сам решает. Он может, например, сохранять своё состояние: бодрый, сонный, спящий, пьяный. Может сохранять одежду и вещи в сумке, которая у него с собой. Может сохранять, куда он сейчас смотрит и куда хочет добраться.

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

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

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

Так что не вижу причин бегать по всей кодовой базе из-за системы сохранений.
180 1014950
>>4945

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


Разве? Для примера, у тебя есть: персонаж, автомобиль, квартал города, город.

Что должен сохранять/загружать персонаж? Это персонаж сам решает. Он может, например, сохранять своё состояние: бодрый, сонный, спящий, пьяный. Может сохранять одежду и вещи в сумке, которая у него с собой. Может сохранять, куда он сейчас смотрит и куда хочет добраться.

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

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

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

Так что не вижу причин бегать по всей кодовой базе из-за системы сохранений.
181 1014951
>>4945

> не улавливаете сути проблемы


Улавливаем.

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


Это всё зависит от игры. Чтобы не пиздеть голословно, давай определимся о какой игре речь? Судя по намёкам выше, про анимации, физику, звуки, речь идёт об убийце скайрима/ведьмака/ассасинов одновременно?
182 1014952
>>4950
Итак, мы определились с тем, какие объекта какие поля хотят сохранять. Дальше-то что? Вот игрок нажал F5, что происходит после этого? Кем регистрируется нажатие F5? Какой код он начинает выполнять? Как он опрашивает персонажей и автомобили? Записывает на забор, тут мы выше определились.
183 1014961
>>4940
Я не сказал что считаю это неправильным, такой код создает зависимость в виде load() save() и том что тебе надо будет при изменениях править код, а нода - создает аналогичную зависимость в дереве tscn и при изменениях тебе надо будет менять поля ноды. Вот и все.
184 1014962
>>4952
Менеджер - перехватчих всех необработанных нажатий обнаруживает нажатие F5, вызывает в синглотоне менеджера сохранений функцию сохранений, та любым способом обходит ноды которые нужно сохранить (хоть рекурсивно все дерево от корня, хоть объекты которые хотят сохранятся могут регистрироваться у него в каком то линейном массиве). Паттерн Visitor кстати тебе что то говорит? Там как раз обратный подход - неважно какая структура и как ее обходить, хоть приставным шагом хоть вприсядку, ты нам главное дай функцию которую вызывать для каждого объекта.
185 1014965
>>4962
Тихо-тихо! Щас синглтонофоб прибежит!
186 1014969
>>4965
У меня есть вариант без синглтона, но я вам его не покажу.
187 1014970
>>4969
Нет у тебя варианта без синглтона, потому что ты не можешь быть умнее разработчиков, которые вхуячили кучу синглтонов выполняющих свои задачи. Был бы ты умнее - ты бы тут не тралил.

> Input


- это синглтон, без него ты не перехватишь копку F5. На этом всё.
188 1014973
>>4970
Я, конечно, имел в виду "не заводя свой синглтон-менеджер сейвов".
Но чисто формально, движок опенсор, и можно и Input подменить своим...
Такое может понадобиться для мультиплеерных кнопок например
189 1014982
>>4951

>Чтобы не пиздеть голословно, давай определимся о какой игре речь? Судя по намёкам выше, про анимации, физику, звуки, речь идёт об убийце скайрима/ведьмака/ассасинов одновременно?


Речь идет об универсальном решении, пригодном для игры любого типа. Например у меня есть сбор игровой аналитики, написанный еще пару лет назад. Я его копипастом вставляю во все свои игры и все работает. С сейвами хуй так сделаешь, каждый раз переизобретенный велосипед приходится вкорячивать.
191 1014987
>>4844

>Всё есть и работает:


Ничоси. А я ж вижел эти функции в доке ещё тогда, до выхода четвёрки, но придал значения именно из-за неочевидных названий.
Энивей, var_to_str и JSON.stringify дают схожие результаты и одинаково читаемы. Плюс есть ультимативное File.store_var для хранения того же самого в бинарном формате.
wtf.png24 Кб, 780x880
192 1015001
>>4961

>надо будет менять поля ноды


Ты аддон видел? https://github.com/locker-godot/locker
На пикриле - то, что предлагает делать автор аддона.
Возможно, в каких-то ситуациях это имеет смысл...

>>4952

>Вот игрок нажал F5, что происходит после этого?


Самый простой вариант, рекурсивный брутфорс:

>func save() -> Dictionary:


>_ var data := {}


>_ for o in objects: data[o.id] = o.save()


>_ return data


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

>>4970
Разработчики сохраняют старое API, чтоб ты не мучился с обновлением игры на новую версию движка.

>>4987

>дают схожие результаты


Насколько я понимаю, JSON.stringify гарантирует соответствие общепринятому стандарту JSON и позволяет выводить сразу с красивым форматированием, а var_to_str - это чисто внутренняя фича Godot для каких-то внутренних дел, которая ничего не гарантирует и, вроде бы, загоняет всё в одну строку без переносов.
193 1015020
>>4986
Вот уж теперь-то можно начинать делать игры
194 1015024
>>4986
как же хорошо что я еще не начинал делать игру
Синглтон 195 1015047
Точнее, менеджер сохранений.
Висит в памяти в течение всей игровой сессии.
Содержит в себе два словаря, мутабельный и иммутабельный.
Имеет четыре метода: create(key, value, update = false), read(key, default, write_default = false), update(key, value, create = false), delete(key, only_value = false)
Методы работают со встроенными словарями таким образом, что любые изменения вносятся в мутабельный словарь, а при чтении сначала опрашивается мутабельный словарь, если в нём не найден ключ, опрашивается иммутабельный, если и в нём не найден ключ, возвращается дефолтное значение. Если нужно дефолтное значение добавлять в мутабельный словарь, если не найден ключ, то юзаем настройку через аргумент.
Так же есть массив контрольных точек, которыми являются глубокие копии мутабельного словаря. Эти контрольные точки могут быть быстро загружены из массива для быстрой загрузки без поднятия сейвов из файловой системы.
Теперь внимание.
Иммутабельный словарь - это эталонные данные игрового мира, он создаётся один раз при старте игры. Если у игры есть моды/длц, то в момент старта приложения оно опрашивает зарегистрированные моды и они предоставляют свои фрагменты данных в иммутабельный словарь. Этот словарь может быть достаточно большим и его не нужно сохранять постоянно. Он сохраняется один раз, в игровом профиле, который создаёт игрок в начале. Сейв-файлы являются сохранённым мутабельным словарём, работают как инкремент к ворлд-файлу в профиле.
Таким образом менеджер сохранений управляет следующими файлами:
1) ворлд-файл, который сохраняется редко, при создании новой игры внутри профиля, либо при изменении списка модов/длц
2) сейв-файл, один или несколько в зависимости от нужд, сохраняется часто, имеет малый размер, поскольку содержит только изменения относительно эталонного набора данных, впрочем в зависимости от величины игры сейвы тоже могут раздуваться.
3) конфиг-файл профиля, в котором хранятся настройки всего приложения в целом
То есть, игрок может полностью переключиться на другой профиль, с другим миром, сгенерированным на других сидах. Сейвы не будут подходить к ворлду, что является дополнительной защитой от читеров.
Стратегии удаления неактуальных данных являются предметом конфигурации менеджера, можно удалять их, а можно хранить, а можно предоставить эту возможность игроку.
Как происходит процесс сохранения? Устанавливается режим read_only и просто записывается мутабельный словарь в сейв-файл.
Как происходит процесс чекпойнтирования перед боссом? Просто копируется мутабельный словарь в массив чекпойнтов.
Как происходит заполнение мутабельного словаря? А вот тут вступает в дело паттерн обсервер. Объекты, которым требуется сохранить данные о себе, подписываются на КРУД-методы менеджера сохранений и при изменении своих данных, синхронизируют их со словарём. Таким образом идёт "трудолюбивое" формирование сейв-файла для "ленивого" процесса сохранения.
Как происходит загрузка? Вне зависимости от источника загрузки, чекпойнт или файл, сначала устанавливается режим read_only, испускается сигнал начала загрузки, все кто подписан на сигнал, делают свои дела, например встают на паузу и ждут дальнейших указаний. Происходит загрузка и проверка данных, если на этом этапе происходят косяки, испускается сигнал отмены, и все задействованные ноды возобновляют свои дела. Новые данные копируются в мутабельный словарь. Испускается сигнал окончания загрузки. Ноды проверяют, должны ли они существовать и если оказывается, что не должны, они выгружаются, а если оказывается, что должны, то обновляют данные о себе (не сидел у костра, а стоял на скале, например). Затем основная нода игрового мира (слово на букву с), управляющая загрузкой-выгрузкой чанков, также опрашивает менеджер на наличие нод, которые должны быть и загружает их. Загруженные ноды опрашивают менеджер на предмет актуальных данных о себе и действуют. И так пока все не обновятся. Когда все подписанные ноды отчитались об обновлении, испускается сигнал окончания обновления.

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

Вот такой прожект. Разьебите по пунктам, в чём я не прав?
Синглтон 195 1015047
Точнее, менеджер сохранений.
Висит в памяти в течение всей игровой сессии.
Содержит в себе два словаря, мутабельный и иммутабельный.
Имеет четыре метода: create(key, value, update = false), read(key, default, write_default = false), update(key, value, create = false), delete(key, only_value = false)
Методы работают со встроенными словарями таким образом, что любые изменения вносятся в мутабельный словарь, а при чтении сначала опрашивается мутабельный словарь, если в нём не найден ключ, опрашивается иммутабельный, если и в нём не найден ключ, возвращается дефолтное значение. Если нужно дефолтное значение добавлять в мутабельный словарь, если не найден ключ, то юзаем настройку через аргумент.
Так же есть массив контрольных точек, которыми являются глубокие копии мутабельного словаря. Эти контрольные точки могут быть быстро загружены из массива для быстрой загрузки без поднятия сейвов из файловой системы.
Теперь внимание.
Иммутабельный словарь - это эталонные данные игрового мира, он создаётся один раз при старте игры. Если у игры есть моды/длц, то в момент старта приложения оно опрашивает зарегистрированные моды и они предоставляют свои фрагменты данных в иммутабельный словарь. Этот словарь может быть достаточно большим и его не нужно сохранять постоянно. Он сохраняется один раз, в игровом профиле, который создаёт игрок в начале. Сейв-файлы являются сохранённым мутабельным словарём, работают как инкремент к ворлд-файлу в профиле.
Таким образом менеджер сохранений управляет следующими файлами:
1) ворлд-файл, который сохраняется редко, при создании новой игры внутри профиля, либо при изменении списка модов/длц
2) сейв-файл, один или несколько в зависимости от нужд, сохраняется часто, имеет малый размер, поскольку содержит только изменения относительно эталонного набора данных, впрочем в зависимости от величины игры сейвы тоже могут раздуваться.
3) конфиг-файл профиля, в котором хранятся настройки всего приложения в целом
То есть, игрок может полностью переключиться на другой профиль, с другим миром, сгенерированным на других сидах. Сейвы не будут подходить к ворлду, что является дополнительной защитой от читеров.
Стратегии удаления неактуальных данных являются предметом конфигурации менеджера, можно удалять их, а можно хранить, а можно предоставить эту возможность игроку.
Как происходит процесс сохранения? Устанавливается режим read_only и просто записывается мутабельный словарь в сейв-файл.
Как происходит процесс чекпойнтирования перед боссом? Просто копируется мутабельный словарь в массив чекпойнтов.
Как происходит заполнение мутабельного словаря? А вот тут вступает в дело паттерн обсервер. Объекты, которым требуется сохранить данные о себе, подписываются на КРУД-методы менеджера сохранений и при изменении своих данных, синхронизируют их со словарём. Таким образом идёт "трудолюбивое" формирование сейв-файла для "ленивого" процесса сохранения.
Как происходит загрузка? Вне зависимости от источника загрузки, чекпойнт или файл, сначала устанавливается режим read_only, испускается сигнал начала загрузки, все кто подписан на сигнал, делают свои дела, например встают на паузу и ждут дальнейших указаний. Происходит загрузка и проверка данных, если на этом этапе происходят косяки, испускается сигнал отмены, и все задействованные ноды возобновляют свои дела. Новые данные копируются в мутабельный словарь. Испускается сигнал окончания загрузки. Ноды проверяют, должны ли они существовать и если оказывается, что не должны, они выгружаются, а если оказывается, что должны, то обновляют данные о себе (не сидел у костра, а стоял на скале, например). Затем основная нода игрового мира (слово на букву с), управляющая загрузкой-выгрузкой чанков, также опрашивает менеджер на наличие нод, которые должны быть и загружает их. Загруженные ноды опрашивают менеджер на предмет актуальных данных о себе и действуют. И так пока все не обновятся. Когда все подписанные ноды отчитались об обновлении, испускается сигнал окончания обновления.

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

Вот такой прожект. Разьебите по пунктам, в чём я не прав?
196 1015085
Пишите юнит тесты.
197 1015089
>>5085
Дубина! Ты сейчас нарвёшься, блин! Я думаешь не смогу тебя поколотить? Я смогу тебя поколотить, балда!
198 1015101
>>5047

>Он сохраняется один раз, в игровом профиле, который создаёт игрок в начале.


Зачем? Может быть, лучше все 150 Гб из папки игры скопировать в другую папку?

>в чём я не прав


В том, что копируешь данные из res:// в user:// чтобы... чтобы ничего не делать?
image.png798 Кб, 1459x821
199 1015106
Делайте игры. Или изучайте движокю
image.png798 Кб, 1459x821
200 1015107
>>5106
И почему картинка проебалась?
201 1015109
>>5106
Ого, запрещенная картинка.
202 1015110
>>5109
Там была игра
4046.jpg283 Кб, 500x714
203 1015114
>>5106 >>5107
Попробуй сохранить в jpg.
204 1015118
>>5107
перехэшируй
image.png1 Кб, 50x43
205 1015128
Напомните, как, когда и куда нужно сохранять сохранения?
206 1015130
>>5128

>как


Своими руками.

>когда


По запросу/таймеру.

>куда


В папку user://saves/

Вопросы?
207 1015134
А в 4-ке html5 экспорт не поддерживает Compute shaders? Не понмю чтобы видел онлайн демок, документация по этому поводу ничего не говорит, в паре мест видел только упоминание что
misc/compute_shader_heightmap: Not supported on the Compatibility rendering method (which the web platform always uses).
Видимо речь о том что надо WebGPU, а там WebGL, который на GL ES 2.0
208 1015136
>>5134
Я не знаю, братан.
RTFM.png272 Кб, 680x956
209 1015148
>>5134

>документация по этому поводу ничего не говорит


https://docs.godotengine.org/en/stable/tutorials/shaders/compute_shaders.html

>Compute shaders can only be used from RenderingDevice-based renderers (the Forward+ or Mobile renderer).


https://docs.godotengine.org/en/stable/tutorials/rendering/renderers.html

>Choose Compatibility if:


>You are developing for web. In this case, Compatibility is the only choice.

Пусть полежит здесь 210 1015161
Небольшой список лучшего софта в мире
https://www.youtube.com/watch?v=2HxKr0MVwQs
211 1015162
>>5148

>RTFM.png


Какая же классная тяночка. Даже захотелось годот установить.
212 1015182
>>5148
Справедливо, надо было повнимательнее прочитать и сделать логический вывод.
Интересно есть ли смысл нагородить, скажем, WebGPU загрузчик в js-части и коммуницировать с годотом. Так, наверное, можно и Compute Shaders в 3-ке запустить, но непонятно можно ли это вообще и не съест ли коммуницирование выгоду.
213 1015194
>>5182
Ладно, webgpu пока сырой, на пека в фуррифоксе не работает, на мобилке ни в каком.
214 1015227
>>5182
А для чего тебе вообще compute shader в веб-игре?
Что ты там считать собрался на видеокарте? Нейронки?
215 1015230
>>5227
Да разные. Конкретно мне подходит для симуляции водички и boids. И некоторые шейдеры похоже выгоднее делать через компьют, а не через чтение вьюпортов. Все что выигрывает от параллельности.
Написал большой ответ, но стер. Суть в том что это вопрос больше выбора версии движка, и я могу сделать отдельно версию 4-десктоп-компьют для шоукейза, а в вебе все равно оставаться на 3-ке с вариантом помельче, потому что буста не будет.
216 1015232
>>5161
Про блокбенч забыл. Рекомендую.
217 1015234
>>5232
Все хочу следующую игру на SpryTile замутить (аналог CrocoTile3d) или типа https://godotengine.org/asset-library/asset/2873
1657718555882.png32 Кб, 1474x111
218 1015240
Кстати пытался найти, можно ли как то менять размер ячейки октотри в физике или она автоматически считается. Не нашел, но зато наткнулся на упоминание в Jolt рекомендуемых размеров физ объектов (помню несколько раз вопрос поднимался в треде)
Чтобы симуляция была точнее, динамическим объектам следует быть:
размером от 0.1 до 10 метров,
иметь скорости от 0 до 500 м/c,
гравитация от 0 до 10 м/с^2.
Статическим объектам следует быть от 0.1 до 2000 метров длиной.
То есть не стоит пытаться симулировать молекулу скачущую по имперскому крейсеру.
219 1015253
>>5240

>500 м/c


Ради интереса глянул, это 1000 узлов, 1800 км/ч, то есть дозвуковые самолеты.
Блин, получается что и у огнестрела (типа калаш, m-16), и у танковых снарядов еще времен второй мировой скорость обычно раза в 2 выше.
220 1015264
>>5253
Скорость в играх обычно сильно ниже 500 м/с, но физические симуляции тут ни при чём - просто игре потребуется загружать очень много декораций для движения на такой скорости где-либо кроме чистого космоса. Для реалистичных снарядов используются рейкасты; кидать RigidBody3D рационально только в случае какой-нибудь гранаты/ракеты/шара плазмы. Вообще, если ты делаешь игру, а не симулятор, то заботиться тебе придётся совсем о другом. Игры постоянно используют уловки ради фана игрока.

Для примера, скорость машин в GTA 5 намного ниже реалистичной, а игровой спидометр завышает свои показания. Почему? Потому что даже на SSD игра не всегда успевает подгружать нужные чанки города, а удерживать их все в оперативной памяти не может. Однако, это техническое ограничение скорости не мешает миллионам игроков наслаждаться игрой.
221 1015266
>>5264
Только не рейкастами, а вычислением баллистической траектории, а так да.
Можно сделать вывод проще - если игра мультяшная, то можно и медленные пульки ригидобдями, а если симулятор, то надо свою баллистику и аэродинамику.
222 1015267
>>5266

>медленные пульки ригидобдями


>свою баллистику и аэродинамику


Или рейкасты, как в 99% шутеров.
image.png956 Кб, 2000x1396
223 1015278
Мигель Де Икаса если кто из красноглазых ИТТ его помнит, везет Годот на iOS.
224 1015279
>>5278
Пик с айпада.
225 1015283
>>5278
Лидер Mono, вроде, который трудновато было пропихивать на iOS (потому что у эппла был запрет на виртуальные машины в прогах - а то вдруг что то скачает в обход них и выполнит)
image1,8 Мб, 1280x720
226 1015304
давно не интересовался Годотом, потому что планировал в голове свои будущие шедевры, а тут такое... больше нет поводов НЕ делать игры, пиздец...
227 1015305
>>5304

>давно


С 3.5?
228 1015309
>>5305
с 4.3.1
229 1015310
>>5309
ой, т.е. с 4,3,0
1704543771083.png1,2 Мб, 1295x734
230 1015311
>>5304
Ждём...
231 1015313
>>5309
Недостаточно долго планировал.
1743239481557.mp43,2 Мб, mp4,
852x480, 1:08
232 1015315
>>5305
>>5309
>>5310
Нихуя вы зумеры, я как на 3.0.6 обломался с шейдерами и словил дизмораль с прокрастинацией, так и сижу жду когда сделают заебись.
233 1015325
>>5315
У тебя там кто-то тонет.
234 1015368
>>5325
Игорь.
235 1015435
>>5304 >>5315
Вкатился в Godot 3.2
@
Прошло уже пять лет
@
Десятки папок проектов
@
Ни одной полноценной игры

Учился программировать с 2008...
попытались затроллить годотера.mp418,5 Мб, mp4,
1280x720, 1:48
236 1015441
>>5435
Такая ж хуйня.
А по поводу пикчи: на годоте у нас с тобой хоть недоделки есть, юнити я тоже скачивал, тогда ещё в далёком 2к18 и сразу такое оттржение "фунахуй", закрыл и удалил. Анрил4 дольше продержался, но из-за конпеляции шейдеров постоянной и он меня доебал.

А на годоте заебись, достаётся за полсекунды, в нищепекарне лежит как влитой.
237 1015443
>>5435
>>5441
У вас скоп большой, гарантирую. Теряете интерес задолго до финального результата. Возьмите микроидею на неделю, она неизбежено распухнет до месяца, но месяца должно хватить на удержание интереса. Опубликуете первую полноценную игру - дальше легче пойдет.

Если конечно есть желание реально игры делать, а не играться в движке. Играться в движке тоже норм.
238 1015444
>>5435
У этого на пике вообще убийца гта с той самой возможностью заходить в каждый дом.
239 1015447
>>5443
Да, скоп большой, хочется экшен-слешер в открытом мире с прокачкой, квестами, скиллчеками в диалогах. Но понимание объёма уже пришло.
Я делал мини-игры и доводил до играбельного состояния (тетрис, сапёр и т.п.) В общем-то сижу и играю. В общем-то цель достигнута. Ведь никто не требовал обязательно публиковать.

А игра мечты? Я уже говорил, ранее, просто сидишь у реки и ждёшь, пока по ней проплывёт релиз игры похожей на твою мечту. Потому что мы все в едином инфополе живём. Родилась у тебя мечта и полетела синхроимпульсом по резонансу Шумана в коллективное бессознательное, начала сниться людям, похожим на тебя. Если ты сам не захочешь реализовать её, то найдутся другие, да и неизвестно, твоя ли это была мечта, или она тоже приснилась тебе однажды.
240 1015464
>>5447

>хочется экшен-слешер в открытом мире с прокачкой, квестами, скиллчеками в диалогах.


Хочется ААА студией быть. А нужно знать свою нишу. Инди ниша удобна, хороша и востребована, особенно сейчас. Делай странное, делай новое, делай маленькое. Пройти игру на час, которая оставит впечатление, может оказаться более ценным экспириенсом для игрока чем 600 часов дрочить вышки в очередном ассассине.
241 1015475
>>5441

>у нас с тобой хоть недоделки есть


И то верно, но хотелось большего...

>>5444

>возможностью заходить в каждый дом


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

Сейчас вот думаю: может, стоило делать декорации, расставляя их как попало, авось вошёл бы во вкус и получилось бы что-то интересное. Когда на всю игру имеется 3.5 плейсхолдера, работать с ней интереса мало, прогресс совсем не ощущается. Да и навалить различного контента низкого качества несложно. Тут главное соблюдать один общий стиль/настроение. В реалистичных ААА унылое "серое" настроение.

>>5443

>У вас скоп большой


А как без этого? Должен быть высокий потанцевал.

>микроидею на неделю


Сделал за вечер твою микроидею - дальше что? В чём интерес публиковать эту микроидею, что 100500 раз реализована во всех цветах и размерах в Google Play? Выбирай любую версию, играй сколько влезет... А, не влезет, потому что микроидея == микроинтерес к ней, развод лоха на просмотр рекламы перед геймплеем. Разумеется, если ты не сливаешь 1000 часов в одну гиперказуалку с одной примитивной механикой...

Понимаю, есть люди, которые 1000 часов сливают в банальный Flappy Bird и обожают повторять его по туториалам, типа "любимый флаппи бёрд, но вместо птички самолётик", но это вообще отдельная тема, и подобным играм в принципе не нужен движок на том уровне, на котором сейчас находится Godot. Им там достаточно выводить PNG в <canvas> тег HTML5.

Какой потанцевал у флаппи бёрд? PNG заменить?

У условного "клона GTA" большой потанцевал, это ж практически свой собственный Garry's Mod, только с нормальным транспортом и сразу большой картой. Направление развития любое можно выбрать и надстраивать новые механики одну за другой.

>>5447

>хочется экшен-слешер


Легко: мобы прут по прямой, герой тупо вращается с гигантским супер-пупер гипер-мечом, VFX вспышки перекрывают 99% экрана. За вечер сделаешь базу, а остальное можно доделать как-нибудь попозже.

>в открытом мире


Понятие растяжимо, но сегодня "открытый мир" == гигантские пустыни, пустыри, пустые поляны и т.д. Следовательно, опенворлд == растянутый филлер. Реализуешь стандартный коридорный экшн, дальше заменяешь загрузочные экраны тупыми пустырями, заставляешь игрока удерживать W всю дорогу. Даже суперпопулярная GTA 5 на этом построена, с этим её дебильным шоссе на 10 км вдоль скучной пустыни. "Слешеры" вообще с камерой сверху вниз, поэтому и подгрузка чанков мира будет проще технически.

>с прокачкой


Это тоже растяжимое понятие, прокачка может быть банальным +1 к урону и всё, никто не ждёт от тебя S.P.E.C.I.A.L. в ноунейм индюшке от соло автора. Переусложнённое дерево прокачки на самом деле проще реализовать в коде, чем понять в игре (тоже филлерный контент, тебе +1 к урону или к защите?).

>квестами


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

>скиллчеками в диалогах


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

>понимание объёма уже пришло


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

Ты просто ищешь оправдания для безделья.

>проплывёт релиз игры похожей на твою мечту


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

Для примера, Vintage Story начиналась как мод для Minecraft (TerraFirmaCraft), но разрабам надоели все подводные камни Minecraft - запилили свою игру. Возникает вопрос, что им мешало просто играть в ванильный Minecraft, не делая свои модификации? Некоторым людям, видимо, хочется чего-то своего, несмотря на провальность концепции (притащили бесполезный реализм ради реализма - зачем?).

>>5464

>Пройти игру на час


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

>ААА студией быть


Много видел hack-n-slash от ААА? Это ж инди жанр. Единственные представители от условного АА+ - это франшизы родом из древних времён. Как понимаю, нишевые жанры не получают финансирования без достаточно широко известного имени франшизы.
241 1015475
>>5441

>у нас с тобой хоть недоделки есть


И то верно, но хотелось большего...

>>5444

>возможностью заходить в каждый дом


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

Сейчас вот думаю: может, стоило делать декорации, расставляя их как попало, авось вошёл бы во вкус и получилось бы что-то интересное. Когда на всю игру имеется 3.5 плейсхолдера, работать с ней интереса мало, прогресс совсем не ощущается. Да и навалить различного контента низкого качества несложно. Тут главное соблюдать один общий стиль/настроение. В реалистичных ААА унылое "серое" настроение.

>>5443

>У вас скоп большой


А как без этого? Должен быть высокий потанцевал.

>микроидею на неделю


Сделал за вечер твою микроидею - дальше что? В чём интерес публиковать эту микроидею, что 100500 раз реализована во всех цветах и размерах в Google Play? Выбирай любую версию, играй сколько влезет... А, не влезет, потому что микроидея == микроинтерес к ней, развод лоха на просмотр рекламы перед геймплеем. Разумеется, если ты не сливаешь 1000 часов в одну гиперказуалку с одной примитивной механикой...

Понимаю, есть люди, которые 1000 часов сливают в банальный Flappy Bird и обожают повторять его по туториалам, типа "любимый флаппи бёрд, но вместо птички самолётик", но это вообще отдельная тема, и подобным играм в принципе не нужен движок на том уровне, на котором сейчас находится Godot. Им там достаточно выводить PNG в <canvas> тег HTML5.

Какой потанцевал у флаппи бёрд? PNG заменить?

У условного "клона GTA" большой потанцевал, это ж практически свой собственный Garry's Mod, только с нормальным транспортом и сразу большой картой. Направление развития любое можно выбрать и надстраивать новые механики одну за другой.

>>5447

>хочется экшен-слешер


Легко: мобы прут по прямой, герой тупо вращается с гигантским супер-пупер гипер-мечом, VFX вспышки перекрывают 99% экрана. За вечер сделаешь базу, а остальное можно доделать как-нибудь попозже.

>в открытом мире


Понятие растяжимо, но сегодня "открытый мир" == гигантские пустыни, пустыри, пустые поляны и т.д. Следовательно, опенворлд == растянутый филлер. Реализуешь стандартный коридорный экшн, дальше заменяешь загрузочные экраны тупыми пустырями, заставляешь игрока удерживать W всю дорогу. Даже суперпопулярная GTA 5 на этом построена, с этим её дебильным шоссе на 10 км вдоль скучной пустыни. "Слешеры" вообще с камерой сверху вниз, поэтому и подгрузка чанков мира будет проще технически.

>с прокачкой


Это тоже растяжимое понятие, прокачка может быть банальным +1 к урону и всё, никто не ждёт от тебя S.P.E.C.I.A.L. в ноунейм индюшке от соло автора. Переусложнённое дерево прокачки на самом деле проще реализовать в коде, чем понять в игре (тоже филлерный контент, тебе +1 к урону или к защите?).

>квестами


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

>скиллчеками в диалогах


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

>понимание объёма уже пришло


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

Ты просто ищешь оправдания для безделья.

>проплывёт релиз игры похожей на твою мечту


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

Для примера, Vintage Story начиналась как мод для Minecraft (TerraFirmaCraft), но разрабам надоели все подводные камни Minecraft - запилили свою игру. Возникает вопрос, что им мешало просто играть в ванильный Minecraft, не делая свои модификации? Некоторым людям, видимо, хочется чего-то своего, несмотря на провальность концепции (притащили бесполезный реализм ради реализма - зачем?).

>>5464

>Пройти игру на час


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

>ААА студией быть


Много видел hack-n-slash от ААА? Это ж инди жанр. Единственные представители от условного АА+ - это франшизы родом из древних времён. Как понимаю, нишевые жанры не получают финансирования без достаточно широко известного имени франшизы.
1737795696549941.jpg715 Кб, 3840x2160
242 1015489
>>5475

>Много видел hack-n-slash от ААА? Это ж инди жанр.


Так все вменяемые слешеры это ААА. Иначе и быть не может. Миллион уникальных анимаций для врагов индюк не потянет. А если все враги будут просто набигать на игрока, то это заебет уже через 5 минут.
243 1015491
>>5475
Отличный гайд как всю жизнь что-то делать но так ничего и не сделать.
image.png1,3 Мб, 1280x720
244 1015492
image.png610 Кб, 916x464
245 1015505
Эти огоньки - hdr?
246 1015510
>>5505
Нет.
247 1015540
Господа, подскажите мне пожалуйста, твердо и четко, если я буду пилить игру на Godot 4.4 используя C#, я смогу сбилдить для андроида? И будут ли какие-то ограничения в связи с этим?
248 1015549
>>5540
Сбилдить сможешь.

Про ограничения сказать трудно.
Насколько я знаю, поддержка там лишь частичная (через Mono и bionic-linux). Так было в 4.2 и не попадалось чтобы это менялось в текущих или в ближайшем будущем
https://godotengine.org/article/platform-state-in-csharp-for-godot-4-2/#android
В этой статье было написано:
uses the linux-bionic Mono runtime, and only supports the arm64 and x64 architectures.

The linux-bionic runtime is a Linux runtime using the Android C library, so it’s basically Android but without the JNI. This means that the Android bindings are not available, so some APIs (such as SSL) will crash the game. Use the Godot APIs when possible to avoid these issues.

Using NativeAOT should also be supported in theory, but it requires using .NET 8.0 and some manual work.

Немного покопавшись, нашел такой PR
https://github.com/godotengine/godot/pull/88803
Соответственно 3 предыдущих пункта отменяются:
Android exports now use the android runtime identifier instead of linux-bionic, this removes the restrictions we previously had:
Adds support for all Android architectures (arm32, arm64, x32, and x64), previously only the 64-bit architectures were supported.
Loads System.Security.Cryptography.Native.Android (the .NET library that binds to the Android OS crypto functions).
For Android, I don't think there should be any more unsupported APIs (starting from Godot 4.4).

Состояние NativeAOT отслежвается тут https://github.com/dotnet/runtime/issues/106748

Честно говоря, я не до конца все это понял. Думаю что твой игровой C# код всегда работал и будет работать. C# либы скачанные через nuget - скорее всего будут. Какая то экзотика, типа c++ либ - скорее всего нет.

По дефолту будет работать какой то anroid экспорт, в котором ограничений меньше, а для неработавшей криптографии написали обертку. linux-bionic с ограничениями подрубится (только?) если ты включишь экспериментальный NativeAOT в настройках csproj. Дефолтный экспорт комиилит в IL, который потом на устройстве конвертируется JIT в программу. NativeAOT бы сразу компилировал в бинарник.
Один момент например, в linux-bionic нет JNI. Вроде бы это значит что нельзя вызывать никакое API JAVA Android. А всякая аналитика, инаппы, камера вроде через него делается?


Сам я не пользуюсь ни 4-кой, ни C#, и давно не делал отдельных андроид версий (делаю только вин и веб)
248 1015549
>>5540
Сбилдить сможешь.

Про ограничения сказать трудно.
Насколько я знаю, поддержка там лишь частичная (через Mono и bionic-linux). Так было в 4.2 и не попадалось чтобы это менялось в текущих или в ближайшем будущем
https://godotengine.org/article/platform-state-in-csharp-for-godot-4-2/#android
В этой статье было написано:
uses the linux-bionic Mono runtime, and only supports the arm64 and x64 architectures.

The linux-bionic runtime is a Linux runtime using the Android C library, so it’s basically Android but without the JNI. This means that the Android bindings are not available, so some APIs (such as SSL) will crash the game. Use the Godot APIs when possible to avoid these issues.

Using NativeAOT should also be supported in theory, but it requires using .NET 8.0 and some manual work.

Немного покопавшись, нашел такой PR
https://github.com/godotengine/godot/pull/88803
Соответственно 3 предыдущих пункта отменяются:
Android exports now use the android runtime identifier instead of linux-bionic, this removes the restrictions we previously had:
Adds support for all Android architectures (arm32, arm64, x32, and x64), previously only the 64-bit architectures were supported.
Loads System.Security.Cryptography.Native.Android (the .NET library that binds to the Android OS crypto functions).
For Android, I don't think there should be any more unsupported APIs (starting from Godot 4.4).

Состояние NativeAOT отслежвается тут https://github.com/dotnet/runtime/issues/106748

Честно говоря, я не до конца все это понял. Думаю что твой игровой C# код всегда работал и будет работать. C# либы скачанные через nuget - скорее всего будут. Какая то экзотика, типа c++ либ - скорее всего нет.

По дефолту будет работать какой то anroid экспорт, в котором ограничений меньше, а для неработавшей криптографии написали обертку. linux-bionic с ограничениями подрубится (только?) если ты включишь экспериментальный NativeAOT в настройках csproj. Дефолтный экспорт комиилит в IL, который потом на устройстве конвертируется JIT в программу. NativeAOT бы сразу компилировал в бинарник.
Один момент например, в linux-bionic нет JNI. Вроде бы это значит что нельзя вызывать никакое API JAVA Android. А всякая аналитика, инаппы, камера вроде через него делается?


Сам я не пользуюсь ни 4-кой, ни C#, и давно не делал отдельных андроид версий (делаю только вин и веб)
image.png25 Кб, 408x431
249 1015554
250 1015557
>>5554
Это только про факт что "теперь поддерживается не только 64 бит".
Везде, и в документации, и в issue указывают что C# в Android - экспериментальный.
251 1015560
>>5549
Ахуеть ты подробно ответил, спасибо! Только что удалось собрать билд с гугловской рекламкой. Билд с c++ либой не собрался. >>5554
Могу подтвердить, твердо и четко, проект собирается. Фух, гора с плеч, не придется опять скакать с версии на версию
image.png26 Кб, 512x512
252 1015609
Делойте игры
253 1015642
>>5609
Бля, как же ты заебал уже.

Всё. Аноны! Давайте на зло ему не делать игры! Не поддадимся на его наглые провокации!
254 1015651
>>5642
Он пишет эти посты во время своих перерывов, делая игры. Пару тредов назад говорил. У тебя же нет игр, как у безыгорника. Покажи свои игры.
255 1015652
>>5651
Тред про движок, а не про делание игр.
256 1015655
>>5652
Движок-то для делания игор. Ну и приложений. Делай игру и/или приложение. Давай, раз-раз.
ну и нахе.png177 Кб, 480x270
257 1015673
А вы хотели бы делать игры на Нахе?
Многие говорят, дескать, ГДСкрипт похож на Питон, но я тут с утра произвёл изучения и оказалось, что ГДСкрипт намного больше похож на Нахе, а тот в свою очередь похож на доведённый до ума Паскаль скрещенный со скопами скобачьками из си.

Посмотрите.
258 1015699
>>5673
Главное чтобы глаза не царапало как раст. А вообще я у мамы уже вайбкодер, так что пофиг на чем.
259 1015802
>>4424
Тухляк, но че бы не ответить. Бро, прогресс бар тебе в помощь, нихуя не понял че за велосипеды ты мутишь.
260 1015805
>>5802
Бро, пей витаминчики, ешь фрукты, улучшай работу мозга, начнешь понимать.
261 1015812
>>5805
Пояснишь свой негатив? Я реально не пойму че за велосипед. Есть контрол нода такая, прогресс бар называется, ставишь в ней заливку по часовой и вуаля вот тебе кулдаунбар, хоть круг, хоть квадрат, хоть ромб делай, хочешь свою текстуру?, берешь текстурпрогресс бар. Я искренне не понимаю ебли анона с шейдером и клипом, только если он не еба эффект сделать хочет.
262 1015813
>>5812
Где ты увидел негатив? Это был полностью позитивный совет.
Преимущества клипа обсуждались ниже, ты видимо до них не дочитал.
263 1015839
Какие витамины посоветуете чтобы игры делались активнее?
264 1015843
>>5839
чипсы и кола
1743530938876.jpg213 Кб, 591x604
265 1015867
>>5843

> чипсы и


и пиво!
266 1015900
>>5867
ну не, пиво в бабу превращает. а мне нужен высокий уровень теста чтобы стояк был и вдохновение делать игру про секси-девочек
267 1015903
>>5900
В хуябу. Начитаются своих спид-инфов и трясутся.
268 1015906
>>5839
витамин д
ты небось сыч
сидишь дома
солнца не видишь
питаешься говном
витамин д нужон обязательно
269 1015907
>>5839
Кофе + шоколад.
270 1015915
3.х версия годота разрабатывается активней чем весь редот. Смешно.
image.png261 Кб, 421x850
272 1015933
Аноны, эти углы шейдером делают или нет? Если да, то не знаете, где найти похожий?
273 1015937
>>5933
Серые уголки? Скорее обычный спрайт. Не вижу зачем тут шейдер.

А по шейдерам - godotshaders и нейросети.
274 1015958
>>5933
В годоте это можно сделать Control-нодами с темами и стайлбоксами.

> где найти похожий


> шейдер


годотшейдерс дот ком
1685446577248.png376 Кб, 1894x713
275 1015961
>>5933
Уголок можно нарисовать:
-Спрайтом с прозрачностью как сказали выше
-Полигоном (2д или 3д выровненным по камере)
-Line2D
-Кодом через draw_line
-Двумя прямоугольниками (напр. ColorRect)
-Пока не смог придумать способ с клиппингом уголка от квадрата
-Тайлмапом в котором зажгли только нужные квадратики
-Контролами с привязкой к якорям, или например NinePatchRect
-Шейдер, там тоже десяток способов

В общем как ты заметил любой способ позволяющий нарисовать полоску (линию или прямоугольник)
Но шейдер я бы не рекомендовал.

Он получится неоптимальный, там всюду или if ... discard или ALPHA=. Вообще шейдеры прицелов-перекрестий что я видел ужасны. Там чуть ли не SDF приплетают а это куча матана работающего на бедном устройстве пользователя.
Я бы закрутил вершины прямоугольника в угол... Но так просто не получится, ведь у квадрата их всего 4, а subdivide там вроде нет. Не приплетать же 3д для такого...
Ну ладно, приплел.
276 1015964
>>4044 (OP)
Почему Godot так сильно нагружает GPU на Android?

Godot 4.4.1, рендерер "Mobile".
Сцена 2D: один спрайт, три кнопки, текст.
FPS зафиксирован на 20 кадров в секунду.
Анимации отсутствуют, картинка статичная.
Показатели: CPU ~5%, GPU ~80%, 20 FPS.

Для сравнения: Shattered Pixel Dungeon.
В главном меню много спрайтов и анимаций.
Показатели: CPU ~20%, GPU ~5%, 60 FPS.

Почему Godot (Vulkan Mobile) грузит GPU на 80%?
Почему снижение частоты не уменьшает нагрузку?

"Compatibility" использовать не могу из-за бага...
277 1015965
>>5964
А в 4-ке профайлер можно подключить к устройству? Я не пробовал.
Если у тебя 2д, то что за баг в Compatibility? Проще с ним разобраться или попробовать 3-ку, не?
278 1015966
>>5964
Потому что мобильные чипсеты - темный лес. Например мы недавно выяснили что часть мобилок не умеют загружать текстуры выше чем 2048х2048. А некоторые, совсем говняные, лажают с 1024.
279 1015967
>>5966

>часть мобилок не умеют загружать текстуры выше чем 2048х2048


Это какой процент от общего кол-ва?
280 1015969
>>5967
Хз, у меня в гугл-плее процентов 10 отзывов про это было. Полагаю люди с днищефонами видят что игра 2д, значит и на говне мамонта заработает, ставят а она не работает, а тебе потом единичка в отзыв прилетает.
281 1015971
>>5965

>профайлер


Никогда не пользовался. У меня на телефоне одно приложение с названием "игры" поверх открытого приложения показывает нагрузку CPU/GPU с FPS, достаточно точно для оценки производительности.

>что за баг в Compatibility


https://github.com/godotengine/godot/issues/80057
TL;DR: Polygon2D на Skeleton2D не отображается.

>попробовать 3-ку, не?


Я Godot использую, чтобы иметь удобный и при том актуальный инструмент. Если отказываться от всех удобств, тогда лучше перейти на 2D фреймворк, где ничего кроме вывода спрайтов и текста нет.

>>5966

>мобильные чипсеты


При чём тут чипсет, лол, если дело явно в движке?

Повторяю, Shattered Pixel Dungeon летает, несмотря на относительно сложную для 2D рогалика графику. Вулкановский Godot почему-то 80% GPU съедает на минимальную статичную картинку... Очень жаль.

Алсо заметил, что игры на Godot несколько секунд загружаются на Android ДО показа сплеш-скрина, и компиляция шейдеров тут совсем ни при чём, т.к. кэширование шейдеров не ускоряет это ожидание. "Нативные" приложения открываются сразу, или моментально демонстрируют свой сплеш-скрин. Подозреваю, что-то с инициализацией движка.
282 1015972
>>5971

>При чём тут чипсет, лол, если дело явно в движке?


Там стоит слово например.
283 1015973
>>5971
Так по твоей ссылке написано отключить shader cache и все работает.
284 1015974
>>5971

>Алсо заметил, что игры на Godot несколько секунд загружаются на Android ДО показа сплеш-скрина


Это ты спрашивал недавно про C#?
285 1015975
>>5972
Дело не в текстурах, они маленькие у меня.

>>5973

>отключить shader cache и все работает


Пробовал ещё осенью - этот способ не работает.

>>5974
Нет, не пользуюсь C#, но давно Godot использую.

Просто хочется маленькую 2D игрушку на Android...
И чтобы она не выжигала батарейку как 3D экшон.
286 1015976
>>5975
Тогда тебе точно надо 3-ку пробовать...
287 1015977
>>5975
Так а почему ты за полгода не попробовал профайлер-то подключить?
288 1015981
>>5673

>доведённый до ума Паскаль


В каком месте? Haxe больше похож на Java:

>class HelloWorld {


>_ static public function main() {


>_ _ trace("Hello World");


>_ }


>}


В (Object) Pascal такого маразма нет.

>program HelloWorld;


>begin


>_ WriteLn('Hello World');


>end.


Просто и понятно, и без уродливых скобок.
Классы тоже оформляются красиво и понятно:

>type


>_ TWorld = class // описываем класс


>_ _ procedure Hello;


>_ end;


>implementation


>_ procedure TWorld.Hello; // реализуем класс


>_ begin


>_ _ WriteLn('Hello World');


>_ end;


>var World: TWorld; // используем экземпляр класса


>begin


>_ World := TWorld.Create;


>_ World.Hello;


>end.


Так что не надо тут. Haxe не похож на Pascal.
Паскаль-подобные, например: Ada, seed7, Lua.

К сожалению, актуальных движков нет...
288 1015981
>>5673

>доведённый до ума Паскаль


В каком месте? Haxe больше похож на Java:

>class HelloWorld {


>_ static public function main() {


>_ _ trace("Hello World");


>_ }


>}


В (Object) Pascal такого маразма нет.

>program HelloWorld;


>begin


>_ WriteLn('Hello World');


>end.


Просто и понятно, и без уродливых скобок.
Классы тоже оформляются красиво и понятно:

>type


>_ TWorld = class // описываем класс


>_ _ procedure Hello;


>_ end;


>implementation


>_ procedure TWorld.Hello; // реализуем класс


>_ begin


>_ _ WriteLn('Hello World');


>_ end;


>var World: TWorld; // используем экземпляр класса


>begin


>_ World := TWorld.Create;


>_ World.Hello;


>end.


Так что не надо тут. Haxe не похож на Pascal.
Паскаль-подобные, например: Ada, seed7, Lua.

К сожалению, актуальных движков нет...
289 1015984
>>5976

>3-ку пробовать


Вкатился в 3.2, перешёл на 4.0+ и больше не вернусь.

Если тройка такая хорошая - пусть портируют все её достоинства в четвёрку, в чём их проблема? GLES2 забросили - ладно, но ведь GLES3 и там, и там есть. Конкретно зачем откатываться и отказываться от нововведений, упрощающих разработку? Пускай разработчики портируют всё с тройки на четвёрку, конкретно в compatibility режим. Не могут? Почему? Может, в тройке просто-напросто нет ничего такого супер-крутого, что улучшило бы работу четвёрки?

Хватит советовать тройку, это легаси код, который поддерживают из-за 1.5 африканских школьников с древним пентиумом и Windows 2000 или что там у совсем уж нищих людей. У меня древний комп и то нормально тянет Godot 4.x. Другое дело что разрабы накосячили где-то и поэтому рендеринг стал дороже; должны рано или поздно пофиксить как-то. Vulkan (в теории) должен быть производительнее OpenGL, как ассемблерный код производительнее скриптов...
290 1015985
>>5977
Конкретно что ты предлагаешь профайлить?
Вывод одного спрайта на экран, без анимаций?
Отображение кнопок с надписями без иконок?
Рендеринг 20 статичных кадров в секунду?
Там нечего профайлить, это хэллоу ворлд.

Алсо, тот раз депрессия совсем придавила.
291 1015988
>>5985
Для начала надо проверить что факт действительно имеет место.
И убедиться что нет ошибок.
А то очень часто читаешь - о, что то само тормозит. А потом - ой, это я добавлял что то тяжелое для теста (шейдер, постпроцессинг) и забыл отключить.
Во вторых проверить что измеритель не ошибается. Мало ли как он там мерит загруженность, не факт что она такая.
Можно провести такой эксперимент - запустить твою сцену и замерить за сколько часов разрядится телефон со 100% до 0%. Потом то же самое с пиксель данжном. Если существенной разницы не будет, то это или ошибка измерения, или окажется что это вообще не влияет на разряд.
Потом можно уже и закапываться в отладку.
292 1015992
>>5984
С чего бы? Советую, и буду советовать тройку практически всем - для веба, для мобилок. Прекрасный стабильный движок. Пробовал опять в этом году 4-ку на джеме, и что? Были проблемы у многих запустивших. Это версия для ААА-проекта мечты будущего. Буквально пару эффектов нельзя сделать в 3-ке, да и то есть обходные пути. Это наоборот надо портировать удачные фичи из 4-ки обратно в 3-ку более активно. Вулкан в принципе оказался неудачным экспериментом, у многих производительность на нем не выросла, а просела. Может сами автора вулкана верили что он будет быстрее или вводили в заблуждение. А старый глес конечно нельзя просто взять и перенести, ведь теперь архитектура движка строится вокруг апи вулкана.
i9BA0hldx8.jpg101 Кб, 900x600
293 1016018
Как я заебался с вашими этими вулканами и опенжлами. Жил себе не тужил, пилил свое говно в режиме компатибилити, а тут однажды проснулся ночью и подумал: а ведь есть же вулкан. А в нем есть сглаживание. А со сглаживанием у меня картинки не дрожат. А Я ЗАЕБАЛСЯ С ЭТИМ ДРОЖАНИЕМ! Решаю проблему снапанием координат по вектор.1, но там свои особенности вылезают, связанные с моим способом управления. Короче, вулкан и сглаживание. Все збс, если, конечно, не считать того, что сглаживание сглаживает (кто бы мог подумать) и КРИСПНЕСС теряется. Все збс, НО, загружаю я тут несколько десятков тысяч картинок и у меня все зависает нахуй с ошибкой ERROR: Condition "err != VK_SUCCESS" is true. Returning: FAILED. Воспроизвел хуйню в годо 4.2 и выяснилось, что это аут оф видеомемори. Ну ебаный же ты нахуй. Вернулся в компатибилити, там этой хуйни нету. Но оно процессор сильнее грузит. Короче, пиздец, сложно.

Другая хуйня, которая есть и в компатибилити — у этого вашего годо есть какой-то лимит объектов что ли. Что-то в районе 260-270 тысяч ноде2д. А потом оно просто вылетает нахуй. Грустно это. Но. Существование такого уровня масштабности и качества опен сорс софта — само по себе уже чудо, и я должен быть благодарен господу нашему Иисусу уже за это.
294 1016019
>>6018
Какие там у тебя картинки дрожат, шиз?
295 1016020
>>6018

>у этого вашего годо есть какой-то лимит объектов что ли. Что-то в районе 260-270 тысяч ноде2д.


Все что больше 10 тысяч объектов - никто конечно не делает на нодах. Там уже мультимеши, визуалсерверы, самописные ecs. Это уже advanced уровень, пора расти с туториалов.
296 1016022
А что будет если у меня нет пола, и объект падает бесконечно? Переполнение координат, баги, лаги-фризы?
297 1016025
>>6022
Наверное, не знаю. Просто в какой то момент зацикли мир (телепортируй персонажа в такую же комнату на 20 километров вверх)
https://docs.godotengine.org/en/stable/tutorials/physics/large_world_coordinates.html
298 1016027
>>6022
Чем дальше от центра оси координат, тем реже становится float.
299 1016028
>>6025
Не, у меня просто мусор падает вниз и мне лень удалять его или ставить там внизу коллизию.
300 1016029
>>6028
Да блин. Это же элементарно. Просто добавь самому объекту проверку, if global.position.y < -100.0 queue_free()
Или просто 1 Area3D на весь уровень (можно и програмно его создать) и удалять все тела влетевшие по on_body_entered.
301 1016032
>>6029
Но мне лень... Вот бы падали себе и падали.
302 1016034
>>6032
Вот бы я проорал, если это тот же анон который выше экономит на спичках, чуть ли не считает такты ассемблера, а потом тратит ресурсы на пустое обсчитывание буквально мусора физическим движком.
303 1016040
Блин, хотел использовать CompositorEffect, а оказалось это такая низкоуровневая вещь уровня компьют шейдеров
https://github.com/pink-arcana/godot-distance-field-outlines/discussions/1
Базовый бойлерплейт на 420 строчек my ass
https://github.com/pink-arcana/godot-distance-field-outlines/blob/main/project/addons/pa_compositor_effect/base_compositor_effect.gd
Придется и дальше на вьюпортах сидеть, тут разбираться год, и еще и шейдеры на glsl
https://docs.godotengine.org/en/stable/tutorials/rendering/compositor.html
1589128202561.png64 Кб, 1265x206
304 1016041
Блин. Получается для продвинутых спецэффектов все равно придется копировать текстуры.
1743659452640.png1 Кб, 200x200
305 1016050
>>5961

> Но шейдер я бы не рекомендовал.


> Он получится неоптимальный, там всюду или if ... discard или ALPHA=


> Ну ладно, приплел.


Подтверждаю. Ты приплёл. Достаточно от ифов избавиться и уже полегче будет. Четыре уголка - это сумма из трёх прямоугольников, которые можно без ифов сложить и высчитать величину АЛЬФА в каждой точке.
1743663053928.png200x200
306 1016052
>>6050
Я целый час полировал эту пикчу, непонятно ради чего, едрить я аутист.
307 1016056
>>6052
У тебя на пиксель в сторону уехало, инфа 100%, я такой же аутист.
1616808316310.png2 Кб, 250x200
308 1016072
>>6050
Так я это тоже упомянул как неоптимальное - в процитированном: там всюду ALPHA=..
Пиксельный (фрагментный) шейдер затратнее, чем вершинный (вертексный).
Потому что он считается для каждого пикселя. И для них будет несколько рассчетов (ты пишешь про сравнение с тремя квадратами ("чуть ли не SDF приплетают" - такой подход, высчитывать для каждого пикселя, попадает ли он в фигуру, оправдан для очень сложных эффектов, типа фракталов или очень аккуратно сглаженного шрифта)
из которых 99% будут для того чтобы НЕ нарисовать. Если рамка на экране занимает, скажем, 1700 х 900, то это рассчеты для полутора миллионов пикселей каждый кадр (20, 30, 60 раз в секунду) просто греет воздух.
И сравни выполняемую работу в более простом варианте (там совсем немного лишнего, и чуть чуть больше работы для вершин - которые отмечены синим), и в варианте где рисуются только прямоугольники/линии.
А потом удивляются - почему же GPU занят на 80%
saveloadini.png67 Кб, 800x740
309 1016075
Смотрите, использую такую конструкцию для сохранения/загрузки ини-файла с настройками. Все работает, но мне не нравится, что я могу переименовать какую-нибудь переменную, но не внести ее новое название в VARS_TO_SAVE_LOAD. Как бы сделать, чтобы этот массив автоматически наполнялся, а я бы только как-то помечал для этого переменные при их объявлении?
310 1016076
>>6075
Аннотаций в гдскрипт пока не завезли
Есть @export_custom, но не знаю какие там возможности и можно ли узнать пометки из скрипта
Можно банально называть переменные m_krokodil и потом скриптом узнавать все переменные и добавлять m_* в этот массив.
Можно сделать внешнюю утилиту, которая работает как препроцессор с файлом исходника. Ну например превращает какие то комментарии специальные в то что тебе надо. Можно даже тулскриптом на том же гдскрипте и сделать.
311 1016077
>>6075
Сохранял бы сценами - такой проблемы не имел бы. А чем больше/сложнее твои сейвы, тем больше тебе потеть придется. Удачи. Не забудь конверсию версий сейвов написать, кстати.
312 1016079
>>6077
И мультиплеерные кнопки еще нужны.
313 1016080
>>6077

>Не забудь конверсию версий сейвов написать,


Это неотъемлимая часть любой игры крупнее средней.
Не надо относиться к этому как к чему то страшному. Это просто версионирование.
314 1016081
>>6079
С синглтоном под капотом.
315 1016082
>>6080

>Не надо относиться к этому как к чему то страшному.


Надо. Иначе силы уйдут не на то, что необходимо. Был тут один шизик, который пиксели в паддингах кнопок подсчитывал, вместо работы над геймплеем и визуалом.

Версионирование даже во взрослых продуктах часто делает только то, что проверяет версию и говорит что не может загрузить сейвы другой версии, вместо молчаливого падения.
316 1016084
>>6080

>как к чему то страшному.


Почему к страшному? Я отношусь к этому как к унылому, как к верному способу выгореть от своего проекта. Унылую хуиту я и на работе написать могу, причем за деньги.
317 1016085
>>6084
Так это не уныло, а просто стандартно.
318 1016102
>>6082
Смотря где. В ММО в которую я играю уже лет 15, у меня все персонажи сохраняются, даже те которыми я лет 10 не заходил. Способности несколько раз переделывались, поэтому они сбрасываются во фри респек, но уровни и количество очков прокачки всегда сохраняется. Предметов там у персонажа 100-200 и еще банк и сумки ингридиентов. И все это тоже сохраняется, буквально единицы косячных предметов за все годы видел. Обычно предмет или автоапгрейдится на новую версию, или даже работает как легаси мехакника пока его не выкинешь. (Что бывает забавно если какую то механику давно понерфили). Состояние квестов и цепочек квестов тоже запоминается. Правда, там не очень много где можно вынести квестовый предмет, обычно они внутри квеста остаются, поэтому не так много за чем следить надо. Но любой квест/цепочку есть опция рестартануть, не знаю почему в сингл играх такого не делают и вынуждают играть с начала. С другой стоторны какой нибудь факторио или майнркрафт редстоун может сломаться, потому что механики поменялись.
319 1016108
>>6102

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


Потому что все топовые спецы в онлайн-дрочильнях, очевидно же.
320 1016117
>>6018

>ЗАЕБАЛСЯ С ЭТИМ ДРОЖАНИЕМ


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


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

>сглаживание сглаживает и КРИСПНЕСС теряется


Темпоральное сглаживание предназначено для 3D. Множество игроков его ненавидит, кстати говоря... Пиксельным 2D играм концептуально не подходит.

>несколько десятков тысяч картинок


Откуда и зачем? Это чрезвычайно много. Следует оптимизировать через атласы: множество тайлов (спрайтов, деталей) размещается на одну текстуру. Естественно, учитывай ограничения на её размер.

>и у меня все зависает


>это аут оф видеомемори


Странно, у тебя ОС не объединяет VRAM с RAM? Для экономии, можно выключить мип-мапы. Есть ещё несколько вариантов импорта текстур - с разной степенью сжатия, это вроде тоже как-то влияет.

>в районе 260-270 тысяч ноде2д


Слишком большое количество. Способы решения:
- объединять спрайты-детальки в один спрайт ещё до импортирования в движок, если можешь позволить;
- рендерить статичные декорации из множества независимых объектов в SubViewport текстуру, чтобы отображать только один объект вместо тысяч сразу (полезно в ситуации, когда TileMapLayer не подходит);
- реализовать чанковую систему в случае большого открытого мира, подгружая чанки вокруг экрана и освобождая чанки, вышедшие далеко за пределы;
- если игра предлагает зум камеры, обязательно реализовать систему Level of Detail (LOD) как в 3D, подгружая объекты с нужным уровнем деталей;
- обращаться к рендер-серверу движка вручную, не перегружая дерево сцены лишними нодами деталей;
- оптимизировать перегруженные элементы игры - например, объединять одинаковые объекты, близко расположенные друг к другу, в одну общую стопку, отображать только верхний объект в стопке и т.д.

Даже если у тебя в режиме compatibility 250000+ нод нормально работают, у тебя, видимо, мощный ПК, и на более слабом такая игра будет дико тормозить.

Ориентируйся на 20000~30000 нод в сцене.
320 1016117
>>6018

>ЗАЕБАЛСЯ С ЭТИМ ДРОЖАНИЕМ


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


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

>сглаживание сглаживает и КРИСПНЕСС теряется


Темпоральное сглаживание предназначено для 3D. Множество игроков его ненавидит, кстати говоря... Пиксельным 2D играм концептуально не подходит.

>несколько десятков тысяч картинок


Откуда и зачем? Это чрезвычайно много. Следует оптимизировать через атласы: множество тайлов (спрайтов, деталей) размещается на одну текстуру. Естественно, учитывай ограничения на её размер.

>и у меня все зависает


>это аут оф видеомемори


Странно, у тебя ОС не объединяет VRAM с RAM? Для экономии, можно выключить мип-мапы. Есть ещё несколько вариантов импорта текстур - с разной степенью сжатия, это вроде тоже как-то влияет.

>в районе 260-270 тысяч ноде2д


Слишком большое количество. Способы решения:
- объединять спрайты-детальки в один спрайт ещё до импортирования в движок, если можешь позволить;
- рендерить статичные декорации из множества независимых объектов в SubViewport текстуру, чтобы отображать только один объект вместо тысяч сразу (полезно в ситуации, когда TileMapLayer не подходит);
- реализовать чанковую систему в случае большого открытого мира, подгружая чанки вокруг экрана и освобождая чанки, вышедшие далеко за пределы;
- если игра предлагает зум камеры, обязательно реализовать систему Level of Detail (LOD) как в 3D, подгружая объекты с нужным уровнем деталей;
- обращаться к рендер-серверу движка вручную, не перегружая дерево сцены лишними нодами деталей;
- оптимизировать перегруженные элементы игры - например, объединять одинаковые объекты, близко расположенные друг к другу, в одну общую стопку, отображать только верхний объект в стопке и т.д.

Даже если у тебя в режиме compatibility 250000+ нод нормально работают, у тебя, видимо, мощный ПК, и на более слабом такая игра будет дико тормозить.

Ориентируйся на 20000~30000 нод в сцене.
321 1016134
>>6075

>переименовать какую-нибудь переменную


Просто сделай через Dictionary, например:

>var cow # транс-корова (биологически крокодил)


>var milk # даже не спрашивай, откуда оно...


>const MAP: Dictionary[StringName, StringName] = {


>_ &"crocodile": &"cow",


>_ &"tears": &"milk",


>_ # и т.д.


>}


Сохранение:

>for key in MAP:


>_ file.set_value(CS, key, get(MAP[key]))


Загрузка:

>for key in MAP:


>_ set(MAP[key], file.get_value(CS, key, get(MAP[key])))


Итого, у тебя Dictionary состоит из:
1. Key - исходное имя (новой) переменной.
2. Value - актуальное имя (старой) переменной.
Т.е. "исходное": "актуальное", или так:

>"актуальное" == MAP["исходное"]


StringName, по идее, лучше подходит, чем String.
Алсо, типизация Array и Dictionary ускоряет код.

>автоматически наполнялся


Слишком многого хочешь...

>>6102

>В ММО... все персонажи сохраняются


Сохраняются они на сервере, в базе данных.
В худшем случае сисадмин ручками правит.
Алсо, у ММО всего один актуальный "сейв".
А ты думал, почему ММО сервера лежат?

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


>вынуждают играть с начала


Две причины:
1. В сингле ты всю игру за 10 часов проходишь.
В ММОРПГ ты РАБотаешь 10 лет как минимум.
2. В сингле многие не доходят даже до 50%.
В ММОРПГ всё держится на доверии олдов.

Т.е. в ММО это важно, а в сингле можно забить.

>>6077

>сценами такой проблемы не имел бы


Ага, имел бы совсем другие проблемы.

>>6082

>силы уйдут не на то, что необходимо


1. Система версий нужна уже после релиза.
2. После релиза 99.99% проектов уходят на дно.
3. Ушедший на дно проект обновлять смысла нет.
4. ???
5. Профита нет, но и проблем ведь тоже нет - win!
Если анон делает систему версий - он успешный...

>говорит что не может загрузить сейвы


Долгоживущие игры делают как-то так:
- версия 1.2 может открыть сейвы 1.1 и 1.0.
- версия 1.3 может открыть сейвы 1.2 и 1.1.
- версия 1.4 может открыть сейвы 1.3 и 1.2.
И т.д., чтобы кодовая база не раздувалась.

Хочешь открыть сейв из 1.0 в 1.4?
1. Скачай версию 1.2 и пересохрани сейв в ней.
2. Вернись на версию 1.4 и открой сейв из 1.2.
Приблизительно так реализовано в Minecraft.

Важно понимать, что у вас за игра сохраняется?
- Кинематическая новелла на два часа чтения?
- Игра-коллекция пошаговых головоломок?
- Прямой, как кишка, сюжетный экшен?
- Нелинейная экшн-РПГ на 69 часов?
- Симулятор жизни на 9000 часов?
- Айдл-кликер на 100500 часов?
- Песочница на всю жизнь?
- Метаверс с играми?
- Мета-метаверс?
- Реальность?
- Жизнь?
321 1016134
>>6075

>переименовать какую-нибудь переменную


Просто сделай через Dictionary, например:

>var cow # транс-корова (биологически крокодил)


>var milk # даже не спрашивай, откуда оно...


>const MAP: Dictionary[StringName, StringName] = {


>_ &"crocodile": &"cow",


>_ &"tears": &"milk",


>_ # и т.д.


>}


Сохранение:

>for key in MAP:


>_ file.set_value(CS, key, get(MAP[key]))


Загрузка:

>for key in MAP:


>_ set(MAP[key], file.get_value(CS, key, get(MAP[key])))


Итого, у тебя Dictionary состоит из:
1. Key - исходное имя (новой) переменной.
2. Value - актуальное имя (старой) переменной.
Т.е. "исходное": "актуальное", или так:

>"актуальное" == MAP["исходное"]


StringName, по идее, лучше подходит, чем String.
Алсо, типизация Array и Dictionary ускоряет код.

>автоматически наполнялся


Слишком многого хочешь...

>>6102

>В ММО... все персонажи сохраняются


Сохраняются они на сервере, в базе данных.
В худшем случае сисадмин ручками правит.
Алсо, у ММО всего один актуальный "сейв".
А ты думал, почему ММО сервера лежат?

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


>вынуждают играть с начала


Две причины:
1. В сингле ты всю игру за 10 часов проходишь.
В ММОРПГ ты РАБотаешь 10 лет как минимум.
2. В сингле многие не доходят даже до 50%.
В ММОРПГ всё держится на доверии олдов.

Т.е. в ММО это важно, а в сингле можно забить.

>>6077

>сценами такой проблемы не имел бы


Ага, имел бы совсем другие проблемы.

>>6082

>силы уйдут не на то, что необходимо


1. Система версий нужна уже после релиза.
2. После релиза 99.99% проектов уходят на дно.
3. Ушедший на дно проект обновлять смысла нет.
4. ???
5. Профита нет, но и проблем ведь тоже нет - win!
Если анон делает систему версий - он успешный...

>говорит что не может загрузить сейвы


Долгоживущие игры делают как-то так:
- версия 1.2 может открыть сейвы 1.1 и 1.0.
- версия 1.3 может открыть сейвы 1.2 и 1.1.
- версия 1.4 может открыть сейвы 1.3 и 1.2.
И т.д., чтобы кодовая база не раздувалась.

Хочешь открыть сейв из 1.0 в 1.4?
1. Скачай версию 1.2 и пересохрани сейв в ней.
2. Вернись на версию 1.4 и открой сейв из 1.2.
Приблизительно так реализовано в Minecraft.

Важно понимать, что у вас за игра сохраняется?
- Кинематическая новелла на два часа чтения?
- Игра-коллекция пошаговых головоломок?
- Прямой, как кишка, сюжетный экшен?
- Нелинейная экшн-РПГ на 69 часов?
- Симулятор жизни на 9000 часов?
- Айдл-кликер на 100500 часов?
- Песочница на всю жизнь?
- Метаверс с играми?
- Мета-метаверс?
- Реальность?
- Жизнь?
322 1016141
>>6075

> мне не нравится, что я могу переименовать какую-нибудь переменную, но не внести ее новое название в VARS_TO_SAVE_LOAD. Как бы сделать, чтобы этот массив автоматически наполнялся, а я бы только как-то помечал для этого переменные при их объявлении?


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

> var krokodil: int = 62500:


> . set(v):


> . . if v != krokodil:


> . . . krokodil = v


> . . . VARS_TO_SAVE_LOAD.append(&"krokodil")



Эх, в шарпе на этот счёт есть автоподстановка имени вызывающей переменной. Там уж точно не забыл бы.
323 1016142
как сделать мультиплеерную кнопку дайте скрипт
324 1016143
>>6142
ты сначала сингловую сделай
325 1016145
>>6102

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


Во-первых, делают.
Во-вторых, в сингле обычно можно загрузиться, а перед началом миссии чекпоинт.
В-третьих, переиграть нельзя в тех играх, где это важная часть геймплея: например, рогаликах; да и в упомянутом майнкрафте тоже. А в условной жта - грузись и переигрывай сколько влезет.
326 1016146
>>6145
Я имел в виду скорее такую ситуацию: у меня есть в папке старый сейв игры, а игра с тех пор уже обновилась и при загрузке в сейве сломанный квест, играй сначала. А ты скорее о случае когда игрок в текущей версии немного откатывает
Кстати майнкрафт вполне переигрывался. У меня был домашний семейный сераер и там просто бэкапилась папка с миром. Пару раз откатывали при какой то кривой непрогрузке или когда кто то упал в лаву из за лага.
inisaveload.png209 Кб, 940x1604
327 1016147
>>6075
Сделал!
https://pastebin.com/raw/uXa4n18F

Для сохранения переменной в ини просто помечаем ее как @export
Это для настроек, не для сейвов

>>6076
>>6134
>>6141
Все это не то, но спасибо энивей
328 1016149
>>6147

> просто помечаем ее как @export


Я думал, ты об этом знаешь, но тебя этот вариант не устраивает. Потому что помеченные на экспорт торчат в инспекторе.
>>6141
Обновить тред
« /gd/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски

Скачать тред только с превьюс превью и прикрепленными файлами

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