Pull to refresh
1
0
Леонид Карих @Lekret

User

Send message

Может самим на вакансии откликаться?) И статьи прикреплять, там может оценят.

Как разработчик на Unity в СНГ, вопрос, почему надо таргетить именно Unity и СНГ?

Даже если мы берём Unity как самый популярный движок по миру, любой ААА движок это всегда C++, самый популярный скриптовый язык среди геймдев плюсовиков это Lua, так что на мой взгляд отличный выбор.

Если ориентироваться на популярность, то скриптовым языком надо добавлять Python или JavaScript, но ориентироваться надо не на вакансии. Движок должен быть ориентирован на целевую аудиторию (не самую широкую из возможных) и использовать соответсующий инструментарий.

К тому же как с Godot, можно прикрутить любой язык, так что C# на стороне скриптинга мы тоже в последствии увидим.

Я так понимаю речь про "ROC theorem: Readable, Optimised and Correct code."? Если да, то это какой-то левый сайт, где нет никакой математики и доказательств, поэтому хз кто осмелился назвать это теоремой. Максимум субъективное рассуждение. Другой "теоремы" найти увы не смог.

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

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

В ECS заметно сложнее наговнить. Это архитектура которая не трубует большого количества времени и не генерирует много техдолга при его нехватке. Запас прочности с этим напрямую связан, беря ECS и строя игру вокруг него ты вряд-ли "промажешь", то есть ты вряд-ли окажешься в этом самом аду.

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

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

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

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

Разница в том, что если ты будешь использовать "традиционную" модель нетворкинга + предикцию для отзывчивости на клиенте ты получишь:
Нажал кнопку -> показал анимацию на клиенте -> передал сообщение по сети -> 50-100мс задержка из-за пинга -> информация о ударе/блоке дошла до другого игрока.

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

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

То есть если ты нажал кнопку на 50мс, длительность удара 300мс, удар дошёл на 150мс, то игрок увидит у себя удар будто он уже 100мс в процессе, естественно с интерполяций, чтобы это не выглядело рвано. Тогда игра получается отзывчивой и "честной", можно легко определить кто раньше нажал блок, кто кого первее ударил и т.д.

https://youtu.be/1JHetORRpfQ?si=YhnkMT6EhSnoPnfN

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

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

Информации по Visual Scripting'у мало, по каким-то сторонним no-code решениям ещё меньше. Вбив "Unity without code" или "Unity visual scripting" получаем 2 ютуб канала.
Абсолютное большинство гайдов для программиста (само слово) включают в себя работу с C#. Если новичок не умеет в C# он теряет почти весь существующий материал для обучения.
Если брать тот-же Unreal, то там бывает сложнее найти плюсовый гайд, чем гайд на BP, а на Unity без C# делать особо нечего.

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

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

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

Данный код не сработает: "Input.GetKeyDown(KeyCode.Space) += Jump;" Статью случайно не GPT писал?)

Что показывает "Пример использования событий и делегатов" в разделе "оптимизация скриптов"? Что там оптимизируется?

"Избегайте использования коллекций, которые часто изменяют свой размер, таких как List<T>. Вместо этого используйте массивы или Queue<T> с заранее заданным размером." Странная формулировка, почему не List с заранее заданным размером? В примере с ObjectPool это можно было бы кстати учесть.

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

За 3 года опыта побывал на 5 проектах, бывали плотные дедлайны, кранчи были пару раз, оба в течении недели, один хорошо оплатили. Чтобы меня кто-то под дулом пистолета заставлял перерабатывать, не помню, не можешь - не работаешь.
Это конечно анекдот, а не статистика, но "кранчат ли у вас" это не вопрос, который я задаю на собесах, поэтому хватит пугать новичков.

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

Касательно Unreal, умные указатели там есть, но из того, что я видел, работая с ним, часто используются сырые, потому что в движке используется сборщик мусора. В Unigine в плюсовой апишке тоже сырые, и погуглив тоже нашёл информацию про сборщик мусора. В новом O3DE всякие Entity/Component тоже по сырым (вроде без GC). Умные указатели видел только в недавнем UltraEngine. Так что все флагманы стараются от умных указателей уйти, пусть даже в сборку мусора.

Я по работе пишу на Unity и C#, с низкоуровневой разработкой игр и движков знаком, но не сильно, только учусь (язык Odin). Но смотря разные видео-лекции, от того же Кейси Муратори, Майка Актона (знаменитый доклад по DOD), или Джонатана Блоу. Все они топят против умных указателей и против массивов указателей в целом.
Мол делай плотно упакованные массивы данных, вместо указателей используй индексы, смотри не на отдельные объекты, а на множества объектов, используй кастомные аллокаторы вместо new, аллоцируй и переиспользуй большие блоки памяти, и твой код будет работать в 5-10 раз быстрее, при тех же усилиях, а умные указатели отпадут за ненадобностью.
Что думаете про подобный подход? Писать как говорят джентельмены выше на практике слишком сложно? Или если оверхед небольшой, то и ладно?

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

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

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

Компоненты по ссылкам видел только в Entitas (C#). LeoEcs, Morpeh, DOTS, Flecs (C++), Bevy (Rust) и тонна других решений независимо от языка данные хранят плотно, имеют запросы/фильтры и т.д.
Значит ли это, что все популярные решения являются DOD ECS по умолчанию? Значит ли это, что используя их мы уже пришли к DOD?

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

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

Если говорить про сам подход, то он мало в чём выигрывает у ECS, я бы даже сказал, что он во многом проигрывает, даже обычному ООП.

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

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

Раз уж поиск компонентов сделан не по типу, а под каждый тип выделен int, то проще не использовать Dictionary, а например внутри каждой сущности сущности сделать массив object[MaxComponentId + 1], где null это отсутствие компонента (раз уж сделали ссылочную обёртку на примитивы, давайте использовать).
Вот так мы изобрели хранение компонентов, как это делает Entitas, массив быстрее создаётся, быстрее работает, а ещё мы либо не мучаем GC на ресайзе Dictionary, либо, если он имеет capacity с запасом, тупо экономим на памяти в несколько раз, и даже логику менять не пришлось, кроме кода отрисовки в редакторе.

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

1

Information

Rating
6,310-th
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Date of birth
Registered
Activity