Шапка: https://hipolink.me/godothread
Предыдущий: >>1026834 (OP)
Архивный: >>1022039 (OP)
Вот тебе идея: сделай законченную игру.

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

1280x720, 0:04
Главное, если зайдёшь в игре в свою квартиру, и увидишь как ты сам сидишь играешь в свою игру, то ни в коем случае не подходи к себе в игре.
Платформа:
extends CharacterBody2D
class_name Player
const SPEED: float = 350.0
func _physics_process(_delta: float) -> void:
var direction: float = Input.get_axis("ui_left", "ui_right")
if direction:
velocity.x = direction SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
Шарик:
extends CharacterBody2D
class_name Ball
const SPEED: float = 300.0
var moving_vector: Vector2 = Vector2.DOWN
func _physics_process(_delta: float) -> void:
velocity = moving_vector SPEED
if move_and_slide():
var collision: KinematicCollision2D = get_last_slide_collision()
var object: Object = collision.get_collider()
if object is Node:
var _node: Node = object
if _node.name == "Blocks":
assert(_node is TileMapLayer)
var blocks: TileMapLayer = _node
#print(collision.get_position())
var colliding_cell: Vector2i = blocks.local_to_map( collision.get_position() + moving_vector )
#print(colliding_cell)
blocks.erase_cell(colliding_cell)
pass
var angles: Array[float] = [-1.0, 1.0]
var random_angle_deg: float = angles.pick_random()
var random_angle_rad: float = deg_to_rad( random_angle_deg )
moving_vector = moving_vector.bounce(collision.get_normal().rotated(random_angle_rad))
Платформа:
extends CharacterBody2D
class_name Player
const SPEED: float = 350.0
func _physics_process(_delta: float) -> void:
var direction: float = Input.get_axis("ui_left", "ui_right")
if direction:
velocity.x = direction SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
Шарик:
extends CharacterBody2D
class_name Ball
const SPEED: float = 300.0
var moving_vector: Vector2 = Vector2.DOWN
func _physics_process(_delta: float) -> void:
velocity = moving_vector SPEED
if move_and_slide():
var collision: KinematicCollision2D = get_last_slide_collision()
var object: Object = collision.get_collider()
if object is Node:
var _node: Node = object
if _node.name == "Blocks":
assert(_node is TileMapLayer)
var blocks: TileMapLayer = _node
#print(collision.get_position())
var colliding_cell: Vector2i = blocks.local_to_map( collision.get_position() + moving_vector )
#print(colliding_cell)
blocks.erase_cell(colliding_cell)
pass
var angles: Array[float] = [-1.0, 1.0]
var random_angle_deg: float = angles.pick_random()
var random_angle_rad: float = deg_to_rad( random_angle_deg )
moving_vector = moving_vector.bounce(collision.get_normal().rotated(random_angle_rad))
Спасибо. А то тред захватили архитекторы душные. Не осталось места простым одноклеточным уебкам.
Ну можем обсудить, я особо не думал, что первое пришло в голову то и сделал. Проблема была только с collision.get_position() + moving_vector, если не добавлять эту писечку то тайлмап ебаный округляет до ячейки в которой шарик
Каждый блок при коллизии с чем угодно (в данном случае) просто делает роскомнадзор. Мячик же в свою очередь умеет только отскакивать.
Можно было и так, но пришлось бы блок делать отдельной сценой и, либо руками расставлять ровно все блоки, либо подгонять чтобы в TileMapLayer она была ровной, а там какое-то несоответствие было, я один раз делал такое и приходилось подбирать позицию картинци в сцене
Во-первых, я бы рекомендовал использовать это:
https://docs.godotengine.org/en/stable/classes/class_physicsbody2d.html#class-physicsbody2d-method-move-and-collide
Потому что move_and_slide() производит много чего абсолютно лишнего для твоего шарика (да и самой платформы), а move_and_collide() сразу возвращает случившееся столкновение, если оно случилось. Но необходимо умножать вектор движения на delta.
Во-вторых, я бы создавал блоки как независимые физические объекты, а не как ячейки тайлмапа, т.к. продвинутые арканоиды навешивают много разных спецэффектов и способностей на блоки. Тайлмап тут чрезмерно ограничивает и при этом избыточен - он предназначен для больших статичных ландшафтов.
Небольшие замечания:
- после "if object is Class" редактор скриптов должен автоматически подставлять нужные поля класса, т.е. присваивать объект к новой переменной не нужно;
- если нужно сравнивать строки, лучше объявить константу с типом StringName и сравнивать с ней;
- class_name должен находиться перед extends, чтоб совпадать с порядком записи внутренних классов.
>>0933
>руками расставлять ровно все блоки
Уровни в арканоидах легко генерировать процедурно.
>Потому что move_and_slide() производит много чего абсолютно лишнего
Можно, но я об оптимизация не думал даже
>>0935
>т.к. продвинутые арканоиды навешивают много разных спецэффектов и способностей на блоки
Не вижу пока проблемы, если приведёшь пример, возможно соглашусь, даже если там какое-нибудь ебанутое переливание света то его можно наложить на блок отдельно
>>0935
>- после "if object is Class" редактор скриптов должен автоматически подставлять нужные поля класса
Вот это не знал, спасибо
>>0935
>если нужно сравнивать строки, лучше объявить константу с типом StringName и сравнивать с ней;
Ну это из разряда микрооптимизаций, там сравнение по имени просто по приколу
>>0935
>class_name должен находиться перед extends
Этот устой я ломаю, мне так логичнее и удобнее чем дописывать перед extends
>>0935
>Уровни в арканоидах легко генерировать процедурно.
Это был просто арканоид за ~полтора часа из которых 15 минут я срал, 10 минут разбирался с неверно определяемой ячейкой тайлмапа, 2 минуты рисовал блоки в асепрайт, 10 минут переделывал коллизии(т.к. потолок и стены сначала были как WorldBoundaryShape и только при запуске годо сказал что ему не нравится их пересечение и пришлось менять на прямоугольники), он мне не интересен как игра, просто анон предложил сделать
Кстати в гугл плее это вполне себе удачная ниша. Только там арканоиды доведены до крайности, вида "шарики множатся х500, а до ломаемых блоков ты добираешься через туннель в 1 пиксель".
Думаю, любая игра с примитивным геймплеем, которую в любой момент можно открыть, поиграть и закрыть, будет удачной для портабл устройств, в том числе и телефона - 2048, судоку туда же.
> Тайлмап тут чрезмерно ограничивает и при этом избыточен - он предназначен для больших статичных ландшафтов.
В чётвёрке в тайлмап добавили возможность сцены как тайлы устанавливать, то есть, представь себе, блоки в тайлмапе это отдельные объекты со спрайтом, телом, областями, частицами, и этим блокам можно прописать любую тряску, какую пожелаешь.
>оптимизация
Это не оптимизация, у тебя шарик будет СКОЛЬЗИТЬ. Функция move_and_slide() по умолчанию делает до 4 отскоков, прежде чем вернуть контроль твоему коду.
>можно наложить на блок отдельно
С тайлмапом это не так удобно, как со сценами. Этот тайлмап выглядит преждевременной оптимизацией.
>мне так логичнее и удобнее
Чем логичнее? Обычно читается так:
>класс по имени Игрок расширяет CharacterBody2D
Наоборот получается нелогично:
>расширяет CharacterBody2D класс по имени Игрок
У нас Йода магистр что ли ты?
>2 минуты рисовал блоки в асепрайт
Вот главная ошибка. Нужно юзать icon.png с Godot.
Интересно, не знал. Не пользуюсь ими вообще. И как, насколько удобно добавлять сцены в тайлы? GridMap позволяет сгенерировать блоки из сцены, но это очень неудобно, по крайней мере как я это помню (давно уже забросил из-за ограниченности GridMap).
>Это не оптимизация, у тебя шарик будет СКОЛЬЗИТЬ. Функция move_and_slide() по умолчанию делает до 4 отскоков, прежде чем вернуть контроль твоему коду.
Ой всё
>С тайлмапом это не так удобно, как со сценами. Этот тайлмап выглядит преждевременной оптимизацией.
А мне удобно мышкой делать сразу линию блок блоков, паттерны можно сохранять.
>Чем логичнее?
Тем, что годо генерирует первую строку extends и она определяет к какой ноде прикреплен скрипт, и если поменять тип ноды я буду менять первую строчку, она основная, а class_name это просто алиас, не нужно мне это навязывать, я видел это в документации в рекомендации к оформлению кода, но у меня это не укладывается в логическую цепочку потому что она не класс->базовый класс, а класс ноды->базовый класс->алиас
>>0958
>Нужно юзать icon.png с Godot.
Да, проебался.
Недавно смотрел джем один, с довольно серьёзным призом, ведуший не знает про годо ничё, а в игре ГГ - иконка ебаная и он такой спрашивает "Мы что играем за голову робота в банке?"
Ну так же удобно как и любые тайлы. Вместо ссылок на текстуры в тайлсете ссылки на сцены. Инстанцирование/высвобождение идёт прозрачно под капотом, ты просто индексы меняешь в коде, а тайлы уже сами за себя отвечают.
>она определяет к какой ноде прикреплен скрипт
Не обязательно, Godot за этим не следит (лол).
>если поменять тип ноды я буду менять
Не обязательно, можно забить в 99% случаев.
>class_name это просто алиас
Это имя заменяет имя файла, сравни:
>extends "player.gd"
>extends Player
Семантически это одно и то же.
Использовать это имя ты, по идее, будешь чаще, чем строчку с классом-предком. Ибо class_name вовсе не обязателен и его лучше не писать, если твой скрипт объявляет что-то локальное и малозначимое. Т.е. не засоряй поле видимости классов лишними именами; нужные имена пиши на самом видном месте.
Приведу пример. Ты делаешь класс:
>class_name Ball extends RigidBody2D
>func _init(size: float) -> void:
>func bounce() -> void:
Теперь ты можешь делать так, например:
>var ball: Ball = Ball.new(5)
>if node is Ball: (node as Ball).bounce()
>for ball: Ball in get_children(): ball.bounce()
И т.д. Если тебе это не нужно - забей на class_name.
С таким траем нашлась неожиданная тупость - детект коллизии на стороне блока практически мертвый номер, только раздутая поверх коллайдера Area2D (именно больше самого коллайдера) срабатывает. Костыльно короче, хотя думал так будет логичнее и лучше, а получилось как всегда. Похер, первый раз на годоте пишу, попробую проапать этот "арканоид". Вектора отскока не рандомными чтоли сделаю, процедурную генерацию, счет какой-нибудь и тд, хз. Потом видеоуроки от школьника гляну чтоли.
Можно прикрепить скрипт Node на любую ноду. Ты обычно меняешь ноду на что-то более специальное, изначально выбрав что-то более обобщённое: брал, например, Node, а потом решил добавить смещение, поменял на Node2D или Node3D, а код не исправил.
Это баг и о нём знают, но его не решаются фиксить, потому что некоторые научились его использовать в качестве хака для двойного наследования, поэтому исправлять будут только после добавления Traits.
>>0975
>детект коллизии на стороне блока
Можно так, на стороне мячика:
>if "hit" in collider: collider.hit()
>else: # ударились в стену, например
Называется "duck typing": "если крякает, крякаем".
Как бы да, но можно и сам блок сделать Area2D
>>0977
Я так захотел. Я могу всё сделать на Area2D двигая мячик через изменение позиции и это будет работать, а могу подключить Box2D, наверняка есть расширение и сделать там, зачем спрашивать такие вопросы?!
>>0979
>Можно прикрепить скрипт Node на любую ноду
Да, и только так и можно, скрипт "родителя" можно вешать на "наследника". Я обычно меню чарактер на арею или ригид и такой фокус не получается в 99% случаев, это не баг это просто ООП
> будут только после добавления Traits.
Мммм... Трейты в гдскрипте. Ух, заживём.
https://github.com/Earewien/godot-traits
># We can now damage the crate >GTraits.as_damageable(crate).take_damage(10)
Какой-то лишний геморрой...
Предложение Хуана будет работать просто:
>crate.take_damage(10)
>Я могу всё сделать на Area2D двигая мячик через изменение позиции и это будет работать
А вот не факт, там насколько помню если просто менять позицию то будут глюки, поскольку физ движок будет ее перезаписывать своими рассчетами. И правильно двигать через PhysicsDirectBodyState с PhysicsServer2D.BodyState.BODY_STATE_TRANSFORM
https://www.reddit.com/r/godot/comments/1fjuzdg/code_to_teleport_rigidbody2d/
Например в документации прямо сказано
RigidBody2D ... It cannot be controlled directly, instead, you must apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate
If you need to directly affect the body, prefer _integrate_forces() as it allows you to directly access the physics state.
Кто то писал что он перед движением делает body.set_physics_process(false) но у меня есть сомнения что это будет всегда работать в правильном порядке.
Ты чет из моды выпал. Свистопердящие проекты так оформлялись еще когда нейронки под стол пешком ходили всратых собак генерили.

>А вот не факт
Факт. В 3д с арией делал и детектилось. Конечно если ты позицию только не изменишь настолько, что объект "пролетит" свозь коллизию, это называется вроде гхостинг
У ригид боди своя отдельная история, ему в принципе нельзя задавать позицию после того как он уже существует, хотя он так же подвержен этому эффекту и для этого ввели параметр с пика
Звучит так что банально повезло. У игрока на компе будет другой фреймрейт и все.
Так и отлично же. Не отвлекает, а значит наконец то пришло время делать свой клон игрули в которую постоянно залипал там. Лучше же залипать в своей реализации в годоте.
Я тестовую сцену накидал, Area2D - детектор и Area2D - "пуля", пуля постоянно спавнится с увеличением скорости, начиная с 1000, движение происходит примерно по формуле position.x = position.x + speed * delta и был вариант с move_toward в общем то результат одинаковый для любой формулы и process/physics_process - при достижении скорости в 2700 детект не происходит т.к. начинается гостинг.
Далее вместо пули - CharacterBody2D и движением:
velocity.x = speed
move_and_slide()
Тут даёт 2900 и опять гхостинг.
Это для дефолтных коллизий круга и прямоугольника. В принципе терпимо для многих ситуаций, не о прецижион платформере же речь
RigidBody можно менять позицию, но:
- это вызывает какие-то перерасчёты (дорого);
- это сбрасывает симуляцию движения (глупо);
- это может вызвать нежелательный телепорт.
Поэтому рекомендуют не трогать их Transform.
Если вам ригид нужно телепортировать - ОК.
>>1024
Если хочешь быстро и без перескоков - RayCast.
Если лазерной точки недостаточно - ShapeCast.

mOdErN_gAmE_dEvElOpMeNt.png
>RigidBody можно менять позицию, но
Записать ты можешь, но физическому движку на это всё равно, в момент появления рида в сцене его трансформация копируется в физ. движок и обновляется оттуда с большой скоростью, один вариант если ригид "уснёт", ты можешь обновить позицию, но "разбудив" его позиция опять обновится из физ. движка. Если не будить визуально онг "телепортируется" но ты с этим ничего не сделаешь.

Давай, покажи, как ты будешь двумя ифами всё проверять иногда(не в каждом фрейме). Научи нас о великий мыслитель
Не занимайся преждевременными оптимизациями. Если это речь про один единственный объект управляемый игроком - вообще пофиг, там можно на это хоть миллион тактов процессора отложить. Ведь представь там мог быть не шарик, а целый tps контроллер с целыми деревьями анимаций и скелетами костей и все это успевает работать.
>Если не будить
А ты буди его, в чём проблема?
Хорошо, ладно, вот задача:
1. Игрок на VehicleBody заехал в круг телепорта.
2. Телепорт выплюнет игрока за 1 км от входа.
3. Машина остаётся с игроком без изменений.
Предлагаешь queue_free() и новый автомобиль?
А если там много кастомизаций, повреждений?
Так вот из-за кого в новых играх долгие загрузки...
Дебич, тебе расписать два ифа, где Х и Y больше равно / меньше равно нужного значения? Твоё ебало просто в рамку и в музей компьютерных игр с подписью "да, вот дебилы-вайбкодеры вроде него разрушили индустрию".
ТЫ же понимаешь, что по такому принципу написано 90% сегодняшней индюшатины у стиме? Они в основном все не на годоте правда, а на юнити, но это только потому что нормисы все в юнити текут в основном.
>А ты буди его, в чём проблема?
Бля ты бы сам пошёл попробовал, прежде чем хуйню нести про в чём проблема
Какой то жирный троль
Ладно, просто меня в детстве пиздили томиком Страуструпа по голове, не обижайся.
>>0997
>>0995
Ваще трейты (типажи) это разновидность интерфейсов, даже лучшее название чем интерфейс, потому что интерфейс в изначальном смысле это все публичные члены класса/объекта/сущности, называть интерфейсом отдельную сущность было ИМХО ошибкой.
В годоте почти придумали годную замену трейтам/интерфейсам - группы. Достаточно было заложить в гдскрипт механизм валидации вхождения в группу. То есть еще с трёшки есть методы типа call_group() там юзается утиная типизация, если член группы может крякнуть, на нём вызывается кряк, и идёт дальше. Достаточно было в этот механизм добавить строгий режим, чтобы в определение группы можно было вписать метод кряк, и чтобы попытка добавления в группу требовала явно реализовать метод кряк. Ну и всё. Получаем трейты/интрфейсы. Да ещё и с поддержкой в инспекторе.
>>0997
> Предложение Хуана будет работать просто:
Ну ладно. И так сойдёт.
Дружок-пирожок, а ты знаешь сложность твоего сравнения ифами? Она нахуй квадратичная, потому что придется делать ифы всех ко всем. А вот физический движок использует тонну способов оптимизировать это говно, и там сложность логарифмическая, потому что используются пространственные структуры данных для быстрого поиска соседних точек. Более того, в 4 рапира на с++(или раст, не помню уже), а гдс имеет минимальный оверхед на доступ к движковым функциям, что баш на баш даст приемлемую производительность, которая будет гораздо лучше твоих ифов при любом раскладе.
Звучит как что-то не очень сложное что ты можешь сделать аддоном как Proof of Concept.

Хмм... Хмм.... Подумоем.
Ну а я буду иф-елс-ретурн. Оптимизация, шах и мат, и ретурн.
>Более того, в 4 рапира на с++(или раст, не помню уже), а гдс имеет минимальный оверхед на доступ к движковым функциям, что баш на баш даст приемлемую производительность, которая будет гораздо лучше твоих ифов при любом раскладе.
Жопу ставишь? А то я raylib стартану и накатаю пару строк, если на кону твоя жопа.
Ты даже на гдскрипт не смог пару строк накатать, куда тебе языки взрослых людей
То что твои гдс ифы будут медленее физдвижка? Ясен хуй ставлю.
Ребят, вы чего? Какие ифы всех со всеми в арканоиде? Повторю: это игра на гриде. Там все высчитывается через mod % от x, y и смотрится в массивчике.
А по поводу raylib - скажем так, годот вполне может физически из-за недостатков собственного движкового апи не потянуть тот уровень, при котором кривая сложности расчетов обойдет твою наивную реализацию на чистой сишке без всего оверхеда апи движка. Лучше сравнивай анрил/unity il2cpp с raylib, ручаться не стану, но чисто математически и изза лучше проработанного апи - может результат будет лучше.
Ты так позицию мяча просто конвертируешь в ячейку тайлмапы, буквально blocks.local_to_map(collision.get_position()) из кода, в твоём случае будет только ball.position, каждый кадр будешь проверять? и это будет не верно, нужно проверять пересечение круга и прямоугольника.
Скоро фантазёры начнут предлагать вместо использования камеры сдвигать позиции всех объектов относительно игрока.
В целом кстати, я подумал, если кешировать точку прошлой коллизии, а затем при новой проверке в случае ненахождения внутри заданной точки применять метрику чебышева + вектор направления в матрице квадартов, при условии что обьекты не будут телепортироваться, тогда сложность будет o(n) в самом худшем случае (поиск первой коллизии) а в самом лучшем - нам понадобится проверить всего 3 соседа, в чуть худшем - 5 соседей. Но обычно только 3. По идее такой алгоритм будет намного быстрее поиска в пространственной структуре, но он очень не любит телепортации. Надо будет опробовать, спасибо анончики за идею.
>Скоро фантазёры начнут предлагать вместо использования камеры сдвигать позиции всех объектов относительно игрока.
Могу сказать что это реально работает. Размер сетки из квадратов для коллизий можно очень сильно ужать благодаря такой хитрости. Сдвигать их непосредственно может и не надо (хз о чем ты), но вот конвертировать в пространство игрока стоит, операция копеешная. Тогда игрок будет всегда в центре колизионной сетки, а колизионные обьекты - всегда вокруг него, максимально выжимая небольшой обьем сетки в работу.
> самом лучшем - нам понадобится проверить всего 3 соседа, в чуть худшем - 5 соседей. Но обычно только 3
Похоже на правду. ЕМНИП кармаковский рейкастинг в Wolfenstein 3D работал. Там же чисто аналитически можно узнать на пути линии движения в каких точках пересечения со стенками клеток.
З.ы. а для тех кто будет говорить "ну там же круг!!1" - так в квейке БОКС коллайдер заменен точкой, а толщина стен увеличена на нужное значение. С круглым коллайдером все еще проще будет.

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

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

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

>подрубать целый движок годот когда можно использовать рейлиб или сдл
Боюсь представить конечный размер экзешника и библиотек с оверхедами.
>что оверкилл
Для арканоида сам годот оверкил. О том и говори сразу, не хочется годот, хочется свой велик писать. 100% понимания, но тред не об этом.

1080x1080, 0:12
От годота в первую очередь нужен рендер и шейдеры. Потому что вот это заебешься писать. А вот игровая логика физику вовсе не обязана использовать.

>Использовать ЭВМ вместо спичечных коробков и скомканной фольги в картонной обувной коробке
Зарплату родителей этих мажоров представляете?
Допустим, у нас есть такой компонент:
>class_name Health extends Node
>signal changed()
>@export var value: float = 100
>@export var value_max: float = 100
>func take_damage(value: float) -> void:
Композиция - когда объект владеет другим объектом, живущим ровно столько, сколько живёт его владелец. Следовательно, на GDScript мы можем сделать так:
>class_name Enemy extends CharacterBody2D
>@onready var health := $Health as Health
Если мы хотим обратиться к нему, мы просто:
>func give_damage(node: Node) -> void:
>_ if node is Enemy: node.health.take_damage(value)
Либо, если у нас несколько таких классов:
>_ if "health" in node: node.health.take_damage(value)
Это будет работать, ибо мы гарантируем наличие компонента heath всю жизнь конкретного Enemy. В ситуации, когда нода health вдруг пропала, сцена сломается и движок должен выдать ошибку.
Агрегация - когда объект может иметь ссылку на независимый другой объект; объекты могут быть созданы и удалены отдельно друг от друга. В Godot примером является дерево сцены - добавление нод другим нодам равно агрегации по умолчанию. Тогда реализовать доступ к компоненту можно так:
>func give_damage(node: Node) -> void:
>_ var health := node.get_node_or_null("Health") as Health
>_ if health: health.take_damage(value)
Если нода не имеет ноду "Health" в потомках или она неподходящего класса, то "health" будет равно null и последняя строчка просто не выполнится. Можно реализовать неуязвимость, удалив ноду "Health".
Собственно, вопрос: чем "фреймворки" могут быть эффективнее этих стандартных подходов Godot?
Я вообще мимопроходил, у меня смежная задача но просто умник со своими ифами стриггерил. Кстати квады вроде никто не предлагал, предлагали просто дробить пространство на обычную матрицу и по ней шароебиться.
>>1112
Напротив, мы отлично знаем как работает физдвижок. Проблема в том что в годоте в отличии от условного беви вызов физдвижка сам по себе очень нетривиален, и только этими накладными расходами можно умножить на ноль все плюсы от его применения, и может так статься что будет лучше велосипедить.

Отвечает Александр Друзь: В Годоте есть всё что нужно чтобы сделать игру, никакие дополнительные фреймворки не нужны. Все недостающие тебе инструменты ты можешь легко скомпоновать из имеющихся инструментов редактора Годот (как ты и показал в своём посте). Так что ты прав, никаких фреймворков не нужно. Продолжай делать игры.
Ваше очко уходит в зрительный зал
Покажешь где в треде упоминаются фреймоврки для композиции? Или ты про трейты? Трейтам нужна поддержка в языке, да.
>указать nodepath до ноды в другой сохраненной на диске сцене
Это ведь будет работать только если сцены корректно загрузятся?
>но все же можно. Не знаю зачем, но можно
Потому что твой Блокнот не проверяет корректность путей в tscn?
Я помню, как приходилось править пути в AnimationPlayer через Блокнот, потому что я как-то не так переместил какую-то ноду и все пути поломались, и Godot не мог их восстановить, ссылаясь на какую-то больше не существующую или перемещённую ноду. Пришлось открыть tscn в Блокноте и вручную пофиксить эти пути - всё заработало.
Для такого фикса править tscn вручную приемлемо, в остальных случаях не рекомендую даже заглядывать туда, потому что всё это генерируется редактором и перезаписывается, поэтому ручные правки скорее всего исчезнут при следующем сохранении сцены.
>Это ведь будет работать только если сцены корректно загрузятся?
Ага. На самом деле я это обнаружил сохранив группу нод по ПКМ -> save branch as scene, и у одной из сохраненных нод был нодпас указан на ноду, не попавшую в сохраненную группу.
>в остальных случаях не рекомендую даже заглядывать туда
Хорошо, мам, я перестану заглядывать годот-тян под юбку. Нет.
Аддон, который мы все тайно жаждали, но боялись попросить:
https://store-beta.godotengine.org/asset/joyless/you-can-do-it/
https://godotengine.org/asset-library/asset/3267
>Anime girls motivate you every 15-30 minutes.
>Features:
>- Girls holding programming books
>- Nice girls to compliment you
>- Chill girls to greet you
>- Mean girls to insult you
>- Collect girls in the catalog
Based & gachapilled.
Зачем делать игры, если можно играть в Godot?

Три треда назад было.
>у одной из сохраненных нод был нодпас указан на ноду, не попавшую в сохраненную группу.
Тогда это баг редактора, потому что такого быть не должно. Сцена из-за этого может ломаться.
Я не помню, сталкивался с этим или нет, но 100% видел сломанные ссылки на "чужие" ноды...
Нинужно, у меня такое ирл есть.
Алсо 4пик моделька червяка из конца игры, лепил его, лепил, а в получился хуй, лол, но в игре это сложно заметить.
https://rouw-x.itch.io/deserted

https://github.com/cariad/gdscript-typed-performance
Это называется бенчмарк.
Не забывай, что в нем обычно происходит только одно какое то вычисление массово.
Игра состоит не только из одного этого момента, поэтому может быть суммарный прирост будет всего процентов 5.
>доквы что он работает на 30-50% быстрее?
Бенчмарк тебе уже скинули, хотя мог бы и сам его реализовать всего за пару-тройку минут, например:
>var start_time := Time.get_ticks_usec()
>var a = 0
>for i in range(10_000_000): a += 1
>print("untyped: ", Time.get_ticks_usec() - start_time)
>start_time = Time.get_ticks_usec()
>var b := 0
>for i in range(10_000_000): b += 1
>print("typed: ", Time.get_ticks_usec() - start_time)
Этого должно быть достаточно.
Если хочешь теоретическое обоснование ускорения: нетипизированные переменные - это данные плюс ID, обозначающий тип данных. Зачем нужен ID? Чтобы компьютер знал, что с этими данными делать. Если требуется операция с данными, компьютер сначала проверяет ID, и только потом производит операцию, соответствующую обозначенному типу данных. Т.е. типизация скрывается от программиста, но от неё невозможно избавиться полностью. Компьютер (компилятор или интерпретатор) берёт на себя ответственность за проверку типов вместо тебя.
Когда ты явно обьявляешь типы, ты хранишь только конкретные данные, которые передаются заранее обозначенным операциям. Компьютеру больше нет необходимости проверять тип, потому что ты задал конкретную операцию с данными явным образом. Соответственно, выполнение кода ускоряется - т.к. избавляемся от лишних скрытых от глаз проверок.
Наглядный пример:
>func sum(a, b): return a + b
Оператор "+" может принимать int, float, string, Vector2, Vector2, и, возможно, другие типы. Что должно будет произойти после вызова sum? Несколько примеров:
>print(sum(1, 2)) # 3
>print(sum(1.5, 2)) # 3.5
>print(sum("1", "2")) # "12"
>print(sum(Vector2.ONE, Vector2.ONE)) # Vector2(2, 2)
Чтобы это всё работало, компьютер должен скрытно произвести операцию сравнения, подобную такой:
>match data_type:
>_ TYPE_INT: ... # целочисленное сложение
>_ TYPE_STR: ... # конкатенация строк
И т.д. Очевидно, эти операции тратят какое-то время.
Если мы пишем наш код так:
>func sum(a: int, b: int) -> int: return a + b
То компьютеру больше не нужно угадывать значение операции "+", он просто выполняет целочисленное сложение в любом случае. Естественно, это быстрее.
Конкретную реализацию в GDScript я не видел, и всё объяснение чисто на моей интуиции и опыте разных языков программирования. Могу ошибаться.
Ещё интереснее с типизацией Array: чтобы Array мог принимать любые данные, вместо самих данных там сохраняется ссылка на адрес в памяти. Т.е. сначала необходимо перейти по ссылке, проверить тип, и уже потом выполнить запрошенную операцию. Поэтому "обычные" массивы (Array) в GDScript почти такие же медленные, как и Dictionary (ассоциативный массив). Зачастую выгоднее использовать Dictionary вместо динамического массива с произвольными данными.
>доквы что он работает на 30-50% быстрее?
Бенчмарк тебе уже скинули, хотя мог бы и сам его реализовать всего за пару-тройку минут, например:
>var start_time := Time.get_ticks_usec()
>var a = 0
>for i in range(10_000_000): a += 1
>print("untyped: ", Time.get_ticks_usec() - start_time)
>start_time = Time.get_ticks_usec()
>var b := 0
>for i in range(10_000_000): b += 1
>print("typed: ", Time.get_ticks_usec() - start_time)
Этого должно быть достаточно.
Если хочешь теоретическое обоснование ускорения: нетипизированные переменные - это данные плюс ID, обозначающий тип данных. Зачем нужен ID? Чтобы компьютер знал, что с этими данными делать. Если требуется операция с данными, компьютер сначала проверяет ID, и только потом производит операцию, соответствующую обозначенному типу данных. Т.е. типизация скрывается от программиста, но от неё невозможно избавиться полностью. Компьютер (компилятор или интерпретатор) берёт на себя ответственность за проверку типов вместо тебя.
Когда ты явно обьявляешь типы, ты хранишь только конкретные данные, которые передаются заранее обозначенным операциям. Компьютеру больше нет необходимости проверять тип, потому что ты задал конкретную операцию с данными явным образом. Соответственно, выполнение кода ускоряется - т.к. избавляемся от лишних скрытых от глаз проверок.
Наглядный пример:
>func sum(a, b): return a + b
Оператор "+" может принимать int, float, string, Vector2, Vector2, и, возможно, другие типы. Что должно будет произойти после вызова sum? Несколько примеров:
>print(sum(1, 2)) # 3
>print(sum(1.5, 2)) # 3.5
>print(sum("1", "2")) # "12"
>print(sum(Vector2.ONE, Vector2.ONE)) # Vector2(2, 2)
Чтобы это всё работало, компьютер должен скрытно произвести операцию сравнения, подобную такой:
>match data_type:
>_ TYPE_INT: ... # целочисленное сложение
>_ TYPE_STR: ... # конкатенация строк
И т.д. Очевидно, эти операции тратят какое-то время.
Если мы пишем наш код так:
>func sum(a: int, b: int) -> int: return a + b
То компьютеру больше не нужно угадывать значение операции "+", он просто выполняет целочисленное сложение в любом случае. Естественно, это быстрее.
Конкретную реализацию в GDScript я не видел, и всё объяснение чисто на моей интуиции и опыте разных языков программирования. Могу ошибаться.
Ещё интереснее с типизацией Array: чтобы Array мог принимать любые данные, вместо самих данных там сохраняется ссылка на адрес в памяти. Т.е. сначала необходимо перейти по ссылке, проверить тип, и уже потом выполнить запрошенную операцию. Поэтому "обычные" массивы (Array) в GDScript почти такие же медленные, как и Dictionary (ассоциативный массив). Зачастую выгоднее использовать Dictionary вместо динамического массива с произвольными данными.
>что потом?
Зачем в геймдев вкатился?
Начинай делать свою игру мечты.
Или что-то, что может принести деньги.
Или ищи вакансии джуна на Godot (удачи).
А никто и не шутил.
Нужно пропускать через себя и думать что именно делаешь, и почему так. А не просто переписывать.

Годот вообще может деньги принести?
Или только на Юнити возможно, где индустрия огромная итд?
Смогу ли я хотя б 80 тысяч в месяц поднимать в Годоте стабильно и не сдохнуть с голоду или опять дворником работать идти и продолжать бухать и курить?
Игры могут принести деньги. Не движок. Движок уже приносит деньги Хуану и сотоварищам. Так что делаешь игры и пытаешься их продавать. Если ты умеешь делать интересные игры, ты обязательно заработаешь. Но вообще да, проще вернуться в дворники, так стабильней.
Где бесплатные курсы посмотреть, как сделать платные курсы по производству игр на Годоте?
А гта спб тебе не показать?
Оплачиваемого геймдева не существует, это наеб для гоев. Либо влетаешь по знакомству, либо пилишь киллергейм 10 из 10 сам, пиаришь сам и продаешь сам, да еще успешно, либо всю жизнь работаешь и мечтаешь в стол. А скорее всего только мечатешь и нихуя не делаешь всю жизнь, как и все.
Бля, так и знал что проебался.

>25 долларов - это слишком много
Для жмотов есть бюджетная версия.
А на сэкономленное тянку купим!
Бюджетную... Но зато лёгкую!
Тут всё как с нашим любимым попенсурсом - если хочешь без вирусов и прочих проблем, то конпелируй всё сам себе из исходников. Жидкий силикон продаётся в обычных магазинах для рукоделия - никто не будет спрашивать, что ты там собираешься из него отливать. Главное покупать "platinum cured" силикон - он будет дороже, но безопаснее для здоровья при контакте с телом. Обычный член отлить просто - многие этим занимаются, на Reddit можешь посмотреть подробные инструкции мастеров членоделия, есть даже пошаговые туториалы на Youtube без цензуры.
Хочешь себе синий член в форме Godot, угадал?
А я бы себе лучше Годетту сделал...
Я так понимаю, Годетта будет с членом...
>Годот вообще может деньги принести?
Чел, глянь на результаты опросника по годоту, где разрабов спрашивали, какие игры они делают на годоте. Там абсолютное большинство "делают" 3д фпс шутеры. Да, на годоте. Можешь сам глянуть сколько успешных 3д шутеров было выпущено на этом игровом движке. Судя по всему доступные технологии привлекают всяких дегенератов, поэтому их столько и набежало. А те, кто зарабатывает деньги, в основном на юнити пилят 2д индюшатину, тут ты прав. Исключения конечно есть то тут, то там, вроде вон из успешных у детей на годоте это webfishing или как-то так.
Завидуй потише.
Никакого противоречия. 3д шутеры делают сейчас, значит сделают их позже. 3д шутер делать дольше чем 2д игру. 4-ка не так давно стала популярной.
>большинство "делают" 3д фпс шутеры
Кто тебе это сказал? Ты опрос смотрел?
>сколько успешных 3д шутеров было выпущено
Опрос был о "текущих проектах" (current projects).
Во-первых, коммерческих отчиталось всего 499.
Большинство ещё делает или делало мелкоигры.
Во-вторых, жанры-лидеры в опросе были:
- платформеры (platformer): 3293
- РПГ (roleplaying game): 3217
- пазлы (puzzle): 2499
- рогулайты (rogulite): 2492
- стратегии (strategy): 2287
Шутеры только на 6-й позиции: 2202.
Но под "шутерами" скрываются также 2D проекты.
В-третьих, большинство делают 2D и не трогают 3D.
Почему же "first-person"/"third-person" в топе жанров? Основная причина в том, что это вовсе НЕ жанры, а определённый вид (view) 2D/3D игр любого жанра. Независимо от жанра 3D игра должна иметь камеру, которая может быть только двух типов: FPV/TPV. Становится очевидным, что большинство, кто как-то взаимодействует с 3D, поставил галочку на FPV/TPV. Относительно редко эти термины используются в 2D, поскольку почти всё 2D = TPV, но бывают и 2D FPV.
Ещё раз: "first person (view)" - "вид от первого (лица)".
Не путать с "first person shooter" - "стрелялка с FPV".
P.S. Опрос как всегда плохо составили, на мой взгляд. Особенно обосрались с выбором "жанров" в списке... Например, где там модный "open world survival craft"? "Survival" зачем-то смешали с "battle royale" (wtf?). Вот категории "sports/simulation" и "tycoon/management" - интересно, в какую из них засунуть "colony simulator"? Стратегии немного не про то ведь. А "farm simulator"? Бредовая подборка противоречащих жанров. Ещё и засунули зачем-то FPV с TPV, когда многие 3D игры поддерживают несколько видов камеры сразу. И 2D, конечно же, в большинстве случаев относят к TPV (исключением можно сделать 2D FPV квесты).
>большинство "делают" 3д фпс шутеры
Кто тебе это сказал? Ты опрос смотрел?
>сколько успешных 3д шутеров было выпущено
Опрос был о "текущих проектах" (current projects).
Во-первых, коммерческих отчиталось всего 499.
Большинство ещё делает или делало мелкоигры.
Во-вторых, жанры-лидеры в опросе были:
- платформеры (platformer): 3293
- РПГ (roleplaying game): 3217
- пазлы (puzzle): 2499
- рогулайты (rogulite): 2492
- стратегии (strategy): 2287
Шутеры только на 6-й позиции: 2202.
Но под "шутерами" скрываются также 2D проекты.
В-третьих, большинство делают 2D и не трогают 3D.
Почему же "first-person"/"third-person" в топе жанров? Основная причина в том, что это вовсе НЕ жанры, а определённый вид (view) 2D/3D игр любого жанра. Независимо от жанра 3D игра должна иметь камеру, которая может быть только двух типов: FPV/TPV. Становится очевидным, что большинство, кто как-то взаимодействует с 3D, поставил галочку на FPV/TPV. Относительно редко эти термины используются в 2D, поскольку почти всё 2D = TPV, но бывают и 2D FPV.
Ещё раз: "first person (view)" - "вид от первого (лица)".
Не путать с "first person shooter" - "стрелялка с FPV".
P.S. Опрос как всегда плохо составили, на мой взгляд. Особенно обосрались с выбором "жанров" в списке... Например, где там модный "open world survival craft"? "Survival" зачем-то смешали с "battle royale" (wtf?). Вот категории "sports/simulation" и "tycoon/management" - интересно, в какую из них засунуть "colony simulator"? Стратегии немного не про то ведь. А "farm simulator"? Бредовая подборка противоречащих жанров. Ещё и засунули зачем-то FPV с TPV, когда многие 3D игры поддерживают несколько видов камеры сразу. И 2D, конечно же, в большинстве случаев относят к TPV (исключением можно сделать 2D FPV квесты).
Кто-нибудь тут разбирается в левелдизайне?
Всё понимаю, всё умею... на базовом уровне... Но вот фантазии совсем не хватает ни на что. Как я вообще должен придумывать что-то... эдакое? Везде пишут базовые вещи типа "поставить вышку чтобы игрок заинтересовался", "делать линии, ведущие к цели", "комбинировать передний и задний план" и т.п. Но непонятно, как вообще дойти до чего-то из ничего.
Вот я умею CSG ноды лепить друг на друга. И делал множество пробных "уровней" для своих простых прототипов... Но дальше условных кубов моя мысль отказывается двигаться. Типа, накидал кубы, и что? Конкретной цели у меня нет, сюжета не будет. Мне хотелось просто что-то интересное сделать. Но что? Непонятно, как левелдизайнеры это решают.
Какие-то идеи у меня были, но все они какие-то уж слишком пресные, банальные. Пробовал нейронки - текстовые, графические - они тоже что-то банальное генерируют. Игры чужие смотрел - всё одно и то же. Непонятно... Просто случайный мусор лепить? Но неинтересно же, когда всё налеплено абы как.
А без левелдизана игры не получится.
>Но непонятно, как вообще дойти до чего-то из ничего
Есть каналы разбирающие уровни, найди канал левел дизайнера и попробуй посмотреть. Например левелдизайнер из ремеди https://youtube.com/@kirbuyanin

Ребят, пилю игру на годоте, первый мой проект, эрпэгэ-рогалик. Прошу рейтануть визуальный стиль, в целом игра так и будет выглядеть. Медленно, но верно двигаюсь к концу разработки, многое уже реализовано, скоро буду к звукам приступать.
>доступные технологии привлекают всяких дегенератов
Да. Умный способен на чём угодно сделать игру, пока дегенераты выясняют, чей движок лучше.
Видел тебя в субшоте. Молодец. Красиво выходит.
Освещение встроенными нодами сделал ведь? Попробуй добавить normal map спрайтам камней:
https://docs.godotengine.org/en/stable/tutorials/2d/2d_lights_and_shadows.html#normal-and-specular-maps
Должно получиться интереснее, особенно пол.
Спасибо. Неделю или больше убил на создание освещения, пытался сделать по красоте, чтобы объекты отражали тень, колонны там, сущности всякие. Но столкнулся с тем что физически невозможно сделать так чтобы факел размещённый на стене, мог освещать стену, которая точно также и является окклюдером теней (стены всегда были в тени), и также не смог или не до конца понял как сделать правильный окклюдер анимированным спрайтам, чтобы он учитывал изменение спрайта. По итогу неделю натурально ебался, а по итогу нихуя не вышло, и пришлось делать просто много Light2D с разными текстурами света) Увы, не осилил.
В будущем, когда вся игра будет готова полностью, попробую ещё раз переработать свет полностью, чтобы добавить и тени и прочую муйню, но пока есть вещи поважнее :)
..а ещё что такое "субшот"? Имеешь ввиду скрины в одном из предыдущих тредов? Ибо больше я никуда скрины не публиковал :)
Это как в дизайне персонажей, влияет насмотренность. Чем больше вникаешь в чужой удачный левелдизайн, тем лучше получается свой. У меня игра с упором на левелдизайн, и если в начале я тоже лепил кубы, то теперь прям доволен, вертикальность, разнообразие, крутые формы, ух бля. Тем временем мой каталог с рефами, куда я складываю скрины чужих игр с хорошим дизайном, распух до 2гб. Это моя сокровищница нахуй, а я дракон, собираю все больше и больше.
Норм. В целом выглядит как любой другой пиксельный эрпогэ рогалик. Визуально ничем не выделяется ни в плохую сторону, ни в хорошую.
Все темное, что происходит вряд ли будет понятно. При этом есть свет с градиентом который выбивается из пиксельного стиля.
Пролистал весь тред, не нашёл свои скрины (и слава богу, уже охуел с того что кто-то мои скрины куда-то заливает)
Видимо чел ошибся.
Значит с уникальностью проблемы. Попробуй чтоль шейдер какой сверху накинуть странный. Узнаваемость важна. Если твоя игра выглядит как 50 других игр того же жанра, то, ну, сам понимаешь.
>Ибо больше я никуда скрины не публиковал
>>1732
>кто-то мои скрины куда-то заливает
Даже на Reddit не заливаешь? Я просто точно помню, как видел какие-то посты с рогаликом, который выглядел почти точь-в-точь как твой скриншот... Особенно GUI очень похож был. Автор поста вроде бы спрашивал, мол, "нормальный GUI для рогалика или нет", или что-то в этом роде. Я ещё много постов с разными играми тогда открыл... но сейчас тот пост найти не могу.
>>1696
>невозможно сделать так чтобы факел размещённый на стене, мог освещать стену, которая точно также и является окклюдером теней (стены всегда были в тени)
Я покопался в 2D нодах, и там можно назначить битовые маски источникам света, теням и спрайтам. Если разместить два источника света - на стене и ниже стены - и настроить слои свету, теням и освещаемым спрайтам (нужно всего 2 слоя), тогда можно добиться эффекта "факел виден на освещённой стене, но эта стена отбрасывает тень на пол позади неё". Единственная проблема, которую я так и не смог решить - получается 2 отдельных тени "от пола" (перекрывающая только пол) и "от потолка" (перекрывающая стены). Выглядит нереалистично.
В общем, мне кажется, добиться на 100% реалистичных 3D теней можно только в 3D или какой-то особенной магией шейдеров (там какой-то рейкастинг добавили недавно). У тебя стены на самом деле плоские квадраты, а ты хочешь тени, которые огибают стены, как будто это 3D параллелепипеды, если я правильно понял...
В крайнем случае можно сделать оверлей (через SubViewport), на котором рендерятся 3D тени вокруг 3D параллелепипедов - которые на экране не отображаются. Но с этим подходом возникнуть проблема сортировки по Y, мне кажется. Особенно если источники света будут передвигаться... Да и с таким подходом будет проще сразу всё в 3D сделать, с пиксельными текстурами и 2D персонажами, лол.
Но normal map и specular map в 2D можно использовать вообще без "теней", потому что они работают только на "источниках света". Нужно только выставить значение "height" отличное от нуля (источнику света). Попробовать сгенерировать карту нормалей для нарисованных вручную спрайтов/тайлов можно здесь, должно работать с любым рисунком:
https://cpetry.github.io/NormalMap-Online/
Ну, просто предлагаю вариант, смотри сам, нужно тебе это или нет. Но современные "пиксельные" игры часто используют этот трюк, как мне кажется. Делает картинку живее...
>Ибо больше я никуда скрины не публиковал
>>1732
>кто-то мои скрины куда-то заливает
Даже на Reddit не заливаешь? Я просто точно помню, как видел какие-то посты с рогаликом, который выглядел почти точь-в-точь как твой скриншот... Особенно GUI очень похож был. Автор поста вроде бы спрашивал, мол, "нормальный GUI для рогалика или нет", или что-то в этом роде. Я ещё много постов с разными играми тогда открыл... но сейчас тот пост найти не могу.
>>1696
>невозможно сделать так чтобы факел размещённый на стене, мог освещать стену, которая точно также и является окклюдером теней (стены всегда были в тени)
Я покопался в 2D нодах, и там можно назначить битовые маски источникам света, теням и спрайтам. Если разместить два источника света - на стене и ниже стены - и настроить слои свету, теням и освещаемым спрайтам (нужно всего 2 слоя), тогда можно добиться эффекта "факел виден на освещённой стене, но эта стена отбрасывает тень на пол позади неё". Единственная проблема, которую я так и не смог решить - получается 2 отдельных тени "от пола" (перекрывающая только пол) и "от потолка" (перекрывающая стены). Выглядит нереалистично.
В общем, мне кажется, добиться на 100% реалистичных 3D теней можно только в 3D или какой-то особенной магией шейдеров (там какой-то рейкастинг добавили недавно). У тебя стены на самом деле плоские квадраты, а ты хочешь тени, которые огибают стены, как будто это 3D параллелепипеды, если я правильно понял...
В крайнем случае можно сделать оверлей (через SubViewport), на котором рендерятся 3D тени вокруг 3D параллелепипедов - которые на экране не отображаются. Но с этим подходом возникнуть проблема сортировки по Y, мне кажется. Особенно если источники света будут передвигаться... Да и с таким подходом будет проще сразу всё в 3D сделать, с пиксельными текстурами и 2D персонажами, лол.
Но normal map и specular map в 2D можно использовать вообще без "теней", потому что они работают только на "источниках света". Нужно только выставить значение "height" отличное от нуля (источнику света). Попробовать сгенерировать карту нормалей для нарисованных вручную спрайтов/тайлов можно здесь, должно работать с любым рисунком:
https://cpetry.github.io/NormalMap-Online/
Ну, просто предлагаю вариант, смотри сам, нужно тебе это или нет. Но современные "пиксельные" игры часто используют этот трюк, как мне кажется. Делает картинку живее...
Я тебе больше скажу - видел точь в точь такое же уже опубликованным в стиме, пока в распродажах копался.
Если не сложно, я был бы признателен если бы ты нашёл похожие скрины на Reddit, ибо да, я не публиковал туда ничего.
Насчёт нормал-мапов - я думал об этом, это и реализовать будет не так сложно (до пиксель арта я как раз 3д графикой и текстурированием занимался, понимаю че там к чему) но я хочу сделать прям максимально доступную игру в плане производительности. Если когда нибудь найду способ, было бы круто портировать на какое нибудь древнее говно, типа геймбоя мб или ps1 (вся графика уже нарисована не только в 640х360 но и в 320х180), поэтому пока таких примочек не планирую точно.
Да и похуй на самом то деле, главное что я сам для себя знаю что нигде ничего не спиздил, а что там у кого похоже - хуй с ним. Сейчас каждая вторая игра использует интерфейсы с простыми полупрозрачными панельками без какого либо визуального стиля в принципе. А у меня хотя бы так :)
Вряд ли смогу найти теперь...
>прям максимально доступную игру в плане производительности
Делаешь игру на Godot 3.6? У Godot 4.x требования выше, а Godot 4.5 x64 отказывается от старых и бюджетных процессоров без поддержки SSE4.1/SSE4.2. Но вообще, даже с Godot 3.6 минимальные требования у Godot, ИМХО, выше, чем, скажем, у SDL2 (достаточно для 2D пошагового рогалика). Посмотри исходники Shattered Pixel Dungeon - он, вроде, хорошо оптимизирован для рогалика с графикой под мобилки.
>портировать на какое нибудь древнее говно, типа геймбоя
Есть какие-то инструменты для этого, но наверняка придётся переделать игру на них.
>поэтому пока таких примочек не планирую точно
Старые игры часто "отупляли" при создании портов на очень ограниченное железо. Многие порты на Game Boy были только отдалённо похожими на оригинал с "большой" приставки. Типа оригинальная игра весит ~700 Mb, а "порт" лишь ~2 Mb... Не вижу проблемы сделать навороченную версию на ПК и потом сделать "мини"-версию для древней приставки.

>Все темное, что происходит вряд ли будет понятно.
Наоборот, слишком светло для данжа и слабый контраст.
Пятно света вокруг героя наверняка перемещается за ним.
>свет с градиентом который выбивается из пиксельного стиля
А это уже давно норма для современных "пиксельных" игр...
SDL2 софтверный, если туда добавлять свет, тени, нормали, то не факт что это все будет уже шустро. А шейдеры туда добавлять замучаешься. Насчет SDL3 не знаю, но там скорее всего тоже не все просто.
Я использую godot 4.3, только потому что мне порекомендовали именно его в начале разработки :) Я знаю про пиксель-данжн, он вроде на джаве написан и/или сделан. Очевидно что там лучше с оптимизацией вообще всё, в отличии от проекта созданного на каком либо движке. Но в любом случае, пока что так. Потом, когда будет больше скилла, можно и переносить на другие движки/платформы, а пока что меня и так устраивает всё.

На скриншоте неработающая хрень я тупой.

Короче пока решил хуй забить на вывот дня недели в сам экспорт годота.
Просто сделал, что в зависимости от дня (1, 2, 3) высчитывается день недели который нужно написать.
>и слава богу, уже охуел с того что кто-то мои скрины куда-то заливает
свин гд начинал с этого свою карьеру в 2016, воровал скрины для своего паблика вконтакте