Saphire
Ну, если очень часто одинаковый или аналогичный код используется, лучше в функции, да
Saphire
Потом проще например расширить, переписать или понять всё
Alexey
А далее в отдельные модули. И набор тестов :)
Elias
Когда всё хорошо разбито на функции, то пропадает необходимость в многих комментариях. Обычно я сначала группирую разные части большой функции под комментами, типа -- do X ... -- do Y ... Но потом это удаётся кинуть в функции, и в итоге выходит: doX() doY() И комменты не нужны - названия функций говорят за себя. Приятно, когда такое происходит.
Elias
В моей игре 25 тысяч строк кода (20 на C++ и 5 на Lua) И нет ни одной функции длиннее 30-40 строк. Это радует. :)
Elias
Хотя 30-40 - это уже много зачастую и это скорее исключения из правила.
Snusmumriken
Ты только это, нарисуй схемку связей модулей, хотя бы наследования. Или что-то вроде UML-схемы проекта.
Snusmumriken
Потому что 25к строк - достаточно чтобы в них запутаться даже если они совершенно прямые.
Elias
Пока что не путался, но как-нибудь займусь этим Наследованием много не занимаюсь, использую ECS и это уже избавляет меня от множественного наследования. Так что почти везде больше 1-2 уровней наследования нет.
Elias
Но вот вопрос зависимостей волнует в целом. Есть несколько глобальных менеджеров, типа Event manager, Resource manager, Log manager, Save manager, etc. В идеале хотелось бы без них обходиться, но не так красиво их всегда передавать как аргументы в функции, но с другой стороны это ясно передаёт зависимость функции от какого-то менеджера.
Snusmumriken
А зачем нужно такое количество менеджеров? Я прост обхожусь world'ом, который коллизии считает и колбеки на коллизии дёргает, и "геймрулами", в которых прописывается управление, спавн объектов и критерии победы.
Snusmumriken
Потому что синглтоны это хорошо, но имхо - слишком сильно связывает.
Elias
Event manager позволяет объектам подписываться на ивенты, а так же посылать их Resource - загружает текстуры, звуки и пр. Save - позволяет из любого места обращаться к сэйву и сохранять в него что-то И это не синглтоны, но близко к ним. У меня есть глобальная структура, которая хранит инстансы этих классов, так что потенциально я потом могу создать разные логи, очереди ивентов и пр.
Snusmumriken
Кстати, resource итератором проходит по директориям и подгружает оттуда всякую фигню?
Snusmumriken
Потому что я делал автозагрузчик содержимого директорий "одной функцией".
Snusmumriken
Ну, типа такого грабежа объектов, которые потом можно заспавнить. Привет модам. Если есть баги - в модулях - выведет ошибки подгрузки.
Elias
Да, есть список заранее подгружаемых вещей, но остальные ресурсы грузятся только когда нужны, т.е. в конструкторах менюшек, объектов и пр. Но да, в некоторых играх можно сразу же всё загружать, но мне хочется, чтобы всё грузилось только когда нужно. :)
Snusmumriken
Ну смотри. Один твой объект конфликтует с каким-то другим объектом, но ты этого не узнаешь пока не прогрузишь : )
Snusmumriken
Объём тестирования просто возрастает. И да, это исправляется функцией аналогичной spawn: мы типа проверяем, есть ли у нас класс объекта, который мы хотим заспавнить в кеше, и если нет - подгружаем/добавляем.
B
скжте а можно делать что то вроде документации или чего то подобного, в плане интерактива когда я набирал бы название функции и оно автоподбором мне выдавало варианты то что бы было видно что оно принимает\выдает или краткое описание работы? к примеру пользую VS Code
Elias
Ну да, таких случаев пока не бывало, но могу представить себе. У меня если один объект спавнит другой, то это будет указано в особом компоненте, который подгрузит этот объект
Snusmumriken
В девелоперской версии - сразу всё грузим в кеш, в юзерской - допустим, постепенно. Но да, при первом спавне сложного объекта игра может лагануть, особенно с большим количеством/объёмом звуков. Так что тут реально нет панацеи кроме как грузить всё полностью, но это "замедляет запуск" на целых пять секунд, мда.
Snusmumriken
Доходит до абсурда
Elias
У меня если объект X создастся на карте, то описание и ресурсы этого класса подгружаются. Во время подгрузки загружаются и все остальные зависимости, которые порождает этот объект. Во время геймплея вообще ничего не загружается из ресурсов, разве что катсцены. Мне понравилось, как сделали в Don't Starve. Они там ясно в табличке для каждого типа объекта перечисляют все ресурсы, которые ему нужны
Snusmumriken
Сло-о-ожно и муторно : )
Elias
Snusmumriken
У меня прост коллизии и взаимодействие - на тегах, мол, вешаем на объекты теги и колбеки реакции на столкновение с объектом имеющим тот же тег что и колбек. И ими можно жонглировать, вешая как статусы так и "уникальные теги". Поэтому если нет объекта с которым могли бы столкнуться - нет и вызова колбека. А вот всякие gun.World:spawn('bullet', gun:getPosAndAngle()) - тут класс объекта передаётся как строка, и если мир не нашёл класса bullet - отпишет ошибку, мол "нет пули, не прогружено (((" Но я и сам всё писал, чтобы ебошить что-то такое.
Elias
У меня так же с ивентами И пока таких вот зависимостей не продумывал, у меня вот такие часто используемые классы висят в глобальной подгрузке пока что Но потом буду писать явно - gun может заспавнить bullet, magazine, etc.
Anonymous
мне ваш луа очень питон напомнил
Columbus
Я луа даже не начала биндить к себе в движок, но уже знаю, что луа круто
Anonymous
Луа же тоже интерпретируемый?
Columbus
Луа быстрый, удобный, гибкий, лёгкий итда
Columbus
Только даже луа не спасет от моего лютого говнокода
Anonymous
ну вот, наглая копия Питона :D
Columbus
Не
Columbus
Питон медленный
Columbus
Дико
Anonymous
Зато есть хороший сдк
Anonymous
меня не волнует
Columbus
Юзать питон в играх - засовывать стальную трубу себе в жопу
Anonymous
а не врешь ли ты часом?
Columbus
Луажит
Columbus
Впервые слышк
Columbus
Это как луа + жава?
Columbus
Я знаю что это
Columbus
Жава и сишарп этии страдают
Columbus
Но думаю, что луажит очень трудно имплементить
Elias
Кстати у Lua внезапно самый быстрый JIT код, насколько я знаю 😱👍
Columbus
Потому когда в ближайший месяц - два буду ебошить скрипты в движок
Columbus
То буду юзать обычный луп
Columbus
Луа
Columbus
В движок/прону
Columbus
Прогу*
Snusmumriken
Ну кароч luajit - это когда горячие трассы кода на лету (в процессе исполнения программы) компилируются в машинный код данной архитектуры (к которой относится виртуальная машина), после чего, эти скомпилированные участки начинают работать в 100500 раз быстрее. Прямой код на luajit работает примерно так же, как работал бы на сишке. И ещё есть расширение ffi, позволяющие писать на луа - на сишке без оверхеда.
Columbus
Короче, луажит - обычный жит, только луа
Snusmumriken
Только шедеврально оптимизированный, да. Плюс луа крошечная, и сама почти не даёт оверхеда, в отличии от js/pyton в v8/pypy. https://habrahabr.ru/post/113804/
Columbus
Но мне и обычной луа с головой хватит
Columbus
Потому буду разбираться пока с ней
Snusmumriken
Ну смотря для чего. Игрули и двиглы - хотят много векторных операций и кучу вычислений. Конечно, можно написать на c/c++ модуль, оптимизирующий процесс с теми же векторами/матрицами, но типа luajit/ffi даёт возможность не морочиться.
Columbus
Да, у меня двигло, но там будет очень мало вычислений
Columbus
По сути я думаю все вызовы из с++ вызывать из луа
Columbus
И объекты создавать тоже
Snusmumriken
А я попробовал сделать биндинг steam_api.dll на чистой ffi, и у меня не получилось сделать колбеки, там колбеко-макросы для объектов :< https://pp.userapi.com/c841333/v841333110/27409/NHmm9eleLo0.jpg
Columbus
Я бы сначала сделала обертку стимапи в с++, а потом из скрипта бы вызывала функции обертки
Snusmumriken
Хех, меня напрягает морока обёрток на с/с++ (компиляй перекомпиляй), учитывая, что до того как я понял что не могу сделать колбеки без С++ с ООП, я за плюсы даже не садился, а за ffi - очень даже. На лету скомпилирует хедер и добавит его себе в ядро: http://luajit.org/ext_ffi_tutorial.html
Elias
Мне кажется, что JIT нужен для реально больших вычислений. Типа если 1000 пуль на экране или стратегия с тоннами юнитов А так, большую часть времени будут занимать коллизия и рендеринг, так что сильно морочиться с остальным почти нет смысла, я считаю
Snusmumriken
Коллизия на какой стороне, луа или движковой? : ) Если луа - jit оче пригодится.
Columbus
Физику надо считать в движке, в отдельном потоке
Columbus
А скриптом управлять объектами
Elias
Согласен Но я считаю, что такое лучше на C++ писать И сделать биндинг ивентами довольно просто
Columbus
Я думаю, что лучше еще юзать bullet/box2d
Snusmumriken
Физику надо считать в движке, в отдельном потоке
Ох, а если физику обрабатывать одновременно с управлением, то ты останешься без точности, ибо пока ты двигаешь персонажа кнопками - движок двигает его об коллизию или ещё что-то. bullet/box2d - это пушки по воробьям, в 99% случаев, они неимоверно огромные, жирные, глючные, и годятся в основном для игр с физикой. Если тебе нужен персонаж который прыгает по платформам - придётся самому мутить или что попроще использовать. Bump/hardon collider.
Columbus
Ну, мне кажется, что буллет отлично подходит для разных целей
Columbus
И двигать персонажа можно по-разномк
Columbus
Для физической корректности можно делать что-то вроде addForce в юнити
Snusmumriken
Ну кароч заморочишься об сложность проекта. Физика в отдельном потоке - только для не очень важных объектов, особенно для тех, которые находятся за границами камеры, иначе будет видно дрожания и прочую фигню, что не очень сказывается на геймплее. Не переусложняй, лучше найди другие способы оптимизации именно коллизии. Например, вырезание активных объектов (которые в принципе могут двигаться) по области в одну-две камеры. Если вектор движения близок к нулю - можно усыпить объект, и разбудить после того как его кто-то двинет, и т.д.
Elias
Отдельный поток нужен, если физики дофига и она реалистичная. Для обычных платформеров и РПГ извращаться незачем. :)
Columbus
Ну, у меня не платформер
Snusmumriken
Хе, тут обрезка активных меньше чем камера.