Как стать автором
Обновить

Комментарии 67

А можно уточнить коммерческие прогнозы игрушки, что вы делаете?

Могу конечно ошибаться, и скорее всего ошибаюсь, но мне кажется, что малыми силами можно лишь выпустить небольшую инди игрушку и как-то попытаться зацепиться за деньги. По типу Лимбо, допустим.
Наш план — сделать игру с уникальной механикой (синхронная разрушаемость, командная игра с шаром) и найти свою аудиторию, готовую мириться с малым количеством контента ради специфичного игрового опыта.

А уже с аудиторией превратить малые силы — в большие!

Примерно так :)
Наш план — сделать игру с уникальной механикой (синхронная разрушаемость, командная игра с шаром) и найти свою аудиторию

Выглядит странно, что сначала делается продукт, а потом ищется аудитория, готовая его купить.
> Под впечатлением вот этого выступления
За месяц написали продакшн квалити или «просто рисует куб на Opengl 3.3 с тенями из тутроиалов»?
не очень понятно к чему вопрос, но конечно я не начал писать production quality код за полгода (или сколько там было) экспериментов с haskell.
Расскажите про Blender как редактор сцен и прочего, думаю, это интересно не только rust-игроделам.
Поддерживаю!
Как вы используете Blender: читаете Assimp'ом бинарник blend или экспортируете в какой-то свой бинарный или текстовый формат сцены?
З.Ы. Спасибо за статью :)
в двух словах — из блендера пишем иерархию объектов, метаданные, пути до энтитей с компонентами в отдельный toml + экспортируем отдельно каждый уникальный меш.
assimp не используем, у нас свой формат, основанный на валвоском .smd.
Мне очень нравится идея «синхронной разрушаемости». Странно что никто в гейм индустрии не делал акцент именно на полностью разрушаемом мире. Было бы очень круто и весело иметь шутер, где можно было бы разнести весь мир на куски. Или есть какие то причины, которые просто технологически не позволяют создать подобное?
Очень тяжело считать предсказания в условиях падающих стен, поэтому тяжело сделать быстрый геймплей
Очень дорого считать физику на серверах и почти невозможно построить шутер без авторитарного сервера

Поэтому большим компаниям это не интересно, и, поэтому, у нас с быстрым растом есть все шансы! :)
НЛО прилетело и опубликовало эту надпись здесь
только он и есть, к сожалению :(
Где-то видел то ли интервью, то ли дневники разработчиков Red Faction Guerrilla, там немного рассказывали об оптимизациях физики (она же на PS3/X360 выходила еще) и проблемах с сетью. Говорили, что было очень много упрощений по сравнению с изначальными задумками, и очень много поисков «магических констант». Из-за этого, например, трехэтажное здание может спокойно стоять на одной последней недобитой подпорке, а падающая постройка в процессе падения «складывается» внутрь, исчезает в клубах пыли и оставляет относительно мало обломков. Автомобилей и роботов в сетевом режиме нет из-за непредсказуемости.

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

Чем вам minecraft неугодил? Ну и dwarf fortress?
там не та разрушаемость и не тот жанр.

в майнркафте (более релеванты были бы шутеры типа block n load, ace of spaded) нельзя вытащить самый нижний блок и обрушить мост. Вот именно такой разрушаемости очень мало.
Silent storm имеет приличную графику по совместительству с внушительной разрушаемостью
Проблема в том что если делать игру вокруг разрушения — она будет интересна в первую очередь пироманам и другим юным взрывникам. Не отобьет затрат на производство, которое сопряжено с нехилыми вложениями (да и железо потребуется очень неслабое).
Silent storm это тоже не о том.

Именно в шутерах наличие физики — это не только прикольные взрывы, это, в основном, разные тактические уловки связанные с физикой, каждый раз разные сценарии игры (можно закидать коридор мусором и локация уже полностью меняется, можно всей командой подсадить одного лазутчика на высокую стену что бы он украл шары, хех) ну и всякое такое.
Вы очень корректно описали то, что обычно называется «конкретный геморрой для левел дизайнера».
Именно оттуда растут высокие цены такой разработки. Тоесть полное разрушение = высокие требования к пользовательской станции + песочница + долгая и мучительная разработка.
Ибо, если вы не в курсе, гномья крепость, несмотря на ASCII графику, на больших размерах карты весьма жестко лагает, а бывает и умирает съев всю память. И это при том что там камушки покрупнее майенкрафтовских и никаких щепочек и прочего нет. Аутентично реальному упавшая и расколовшаяся бетонная плита при попытке вычисления этого процесса в реалтайме — просто испарит i7.
Так что максимум на что вы можете рассчитывать в наше время это разрушаемые объекты (на заранее назначенные осколки, которые падают в соответствии с PhysX), и возможно чуть чуть копаемый ландшафт (как в Life is feudal, но адски лагает).
Полное разрушение всего это значит отработка хотябы текстур осколков, моделей деформации (ни в одной игре не видел согнутую физическим движком металлическую балку), моделей разрушения. В общем пока хватит и того что в предыдущем обзаце.
так мы пока что и не готовы крошить бетонные плиты. Для тех игровых моментов что я описал полностью хватает нашего уровня детализации — который в видео в начале поста.
Очень тяжело сделать интересным уровень, который можно легко сломать весь. В лучшем случает как в red faction или Deus Ex: HR. Ломать можно, но только в специально предназначенных для этого местах.
доделаем публичную играбельную версию — прямо в эту ветку комментариев её положу и послушаю фидбек :)
Матчевый бой с полным разрушением (в том числе земли) при наличии гравитации? Вы о связанных с этим проблемах думали? Это как мошонку прибить к красной площади. Дело то нехитрое, но зачем и кто будет в это страдать?
Сделайте бой в поясе астероидов на джетпаках. И ломать все проще и физику можно сделать натуральнее. И типа уникальная на текущий момент ниша. Особенно если отказаться от идеи вязкого космоса.
почем всего то? посмотрите видео! мы ломаем мосты, стены, подпорки всякие.
Пол нерушим!
Если по честному, то в демке вы ничего не ломаете. Кубики как были отдельными объектами, так и остались. Отсутствует деформация объектов. Я даже не уверенн что есть трение как динамический процесс зависящий от площади соприкосновения (тогда бы кубики немного подругому расползались).
В том же Red Faction можно невзначай разрушить мост и остаться на маленьком островке карты, но для решения таких проблем разработчики сделали оружие — реконструктор. Оно просто восстанавливает разрушенные постройки до исходного состояния.
На практике, даже просто тот факт, что уровень в игре создается динамически, например игра предоставляет редактор карт, может дать просадку в производительности. Во всяком случае в Unity так. Из справки Unity:
Оптимизация для CPU — количество draw call (в дальнейшем, DC)
В процессе визуализации любого объекта на экране CPU должен немного потрудиться: выяснить, какие источники света влияют на объект, настроить шейдер и его параметры, отправить команды отрисовки графическому драйверу, который подготовит команды для отправки на видеокарту. Все эти операции могут быть не очень дешёвыми в своей сумме, если у вас есть много видимых объектов.
Для примера, если у вас есть тысяча треугольников, то будет намного дешевле разместить их в одном меше, чем использовать тысячу отдельных мешей для каждого треугольника. Стоимость обоих сценариев для GPU будет примерно одинаковой, но работа, выполняемая CPU для тысячи объектов вместо одного будет намного большей по объёму.

Чтобы снизить нагрузку на CPU, старайтесь уменьшить количество видимых объектов:
Объединяйте близко расположенные объекты: вручную или используя инструмент draw call batching в Unity.
Используйте меньше материалов, объединяйте текстуры в большие текстурные атласы.
Используйте меньше объектов, которые должны визуализироваться несколько раз.
Объединяйте объекты так, чтобы каждый меш содержал хотя бы несколько сотен треугольников и использовал только один Материал. Важно понимать, что объединение двух объектов, использующих разные материалы, не даст увеличения производительности.

Если уровень создан заранее в редакторе, то его можно оптимизировать, объединив объекты в один. Если же он создается динамически, то объекты уже не объединишь. Так же нельзя заранее рассчитать освещение для объектов снаружи, только в помещениях (если, конечно, их внутренний интерьер задан жестко, а не собирается, так же, динамически).
Конечно, готовый движок накладывает дополнительные ограничения. Если делать движок самому, пространство для маневра будет больше. Но тем не менее, неочевидных граблей, просто вагон и маленькая тележка. Это я еще физики не касался. В частности, меня в свое время неприятно удивил тот факт, что в большинстве игр, в отличие от остальных объектов, игрок — не подчиняется физике. Это просто капсула, управляемая примитивным скриптом.
Игру-песочницу намного сложней оптимизировать, просто потому, что там меньше мест, где можно схитрить, и «обмануть» пользователя, создав красивую иллюзию. Многие вещи приходится делать «честно».
Я гдето к тому и веду. Если красиво, правильно и по честному взорвать стенку — появится много новых мешей. Можно искуственно ограничить разрушения балансом (1 бомба на команду и ни каплей больше), но игроки они ведь такие. Возьмут и рванут несущую опору у моста так, что сначала сервер подвиснет считать разрушения, и потом еще в ЦПУ прилетит обсчет пары миллионов новых мешей и он перейдет в режим турбогриля.
Движок под песочницу — идея хороша, но движок должен быть шибко умный. Или заранее все объекты разделдять на субэлементы чтобы не было резкой просадки по производительности. Но это условный плюс. При таком подходе производительность просто изначально будет хреновой и ей падать будет некуда.
Спасибо за обзор, очень не хватало подобного списка с кратким описанием.

И следом пару вопросов:
Кажется на YC мелкала ссылка на результаты опросника про rust, где достаточно много респондентов сказали, что используют nightly-билды компилятора. Есть мысли на этот счет? И какую ветку сами используете?
Как часто приходится юзать unsafe-код?
Не находили memory leak-и в компиляторе/своем коде?
на билд машине для виндового билда использую stable
для разработки использую nightly. Единственное ради чего nighly — я через compiler intristics узнаю всякое для профайлера.
компилятор стабилен, на самых свежих nigtly я видел настоящие баги и падения, но — очень редко. Если хотя бы недельной давности nigtly — то всё вообще путём.

мемори лик был один раз — сервер падал с out of memory (я был удивлён, раст, безопасность, и out of memory?). Оказалось я всё в том же профайлере хранил вообще все фреймы.
Настоящий мемори лик получить практически нереально.

unsafe от безысходности я использовал один раз, и это привело к тому, что я писал мимо памяти, прямо как в c++.
Отвратительный код!
функция была примерно такая https://is.gd/PzW9O4 (без unsafe я бы мог написать только так: https://is.gd/gXIbJx).
я захотел обмануть раст, получить ссылки на элементы массива, да при этом еще и иметь возможность менять массив.
В результате — очевидные проблемы. С помощью unsafe можно взять отвестветнность на себя и делать такие вот вещи, но — лучше не стоит.

В общем — unsafe — опасен! не используйте unsafe :)
Ээ, а вы ссылку не перепутали? Если нет то каким чудом lifetime может сделать код safe?
unsafe позволил написать функцию с такой сигнатурой:
fn get_by_ids<'a>(data : &mut Vec, ids : &HashSet) -> Vec<&'a mut Foo>

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

а безопасная выглядела бы так:
fn get_by_ids<'a>(data : &'a mut Vec, ids : &HashSet) -> Vec<&'a mut Foo>

с такой сигнатурой, раст запретил бы мне делать data.clear() и всё было бы хорошо. И примерно такую сигнатуру можно получить безо всяких unsafe внутри.
Ммм, какое хитрое шаманство, ясно :)
Наверное стоило запустить код, мне почему-то показалось, что они оба валидны

Нет, без unsafe не валиден, будет ошибка компиляции:


<anon>:17:5: 17:9 error: cannot borrow `data` as mutable more than once at a time [E0499]
<anon>:17     data.clear();
достаточно много респондентов сказали, что используют nightly-билды компилятора. Есть мысли на этот счет?


Я тут добавлю, что с тех пор как rustup довели до ума, переключаться между разными версиями компилятора на одной машине стало дико просто. Лично мне ночная сборка бывает нужна, допустим, для локальной установки статического анализатора clippy, что бы не гонять CI-сборки тысячу раз для вычистки новых предупреждений.
Спасибо, поправил в тексте.
Чем так хорош идеевский плагин? Тем что он даёт возможность использовать Идею.
Того минимума, что есть в плагине — достаточно для сносной работы, но при этом открываются не бедные и привычные по другим IDE от IntelliJ возможности и workflow, которые окупают все недостатки пока ещё слабой поддержки Rust.
Приятно видеть, что Rust набирает популярность т.к. язык весьма интересный и перспективный.

Недавно наткнулся на библиотеку векторной графики, разрабатывается она тоже на Rust.
Вот описание с сайта проекта: «Poly­draw is a 2D vec­tor graph­ics en­gine writ­ten in the Rust pro­gram­ming lan­guage for the de­vel­op­ment of rich in­ter­act­ive ap­plic­a­tions and games.»

Вот ссылка на GitHub: Polydraw

Интересно, зачем они все привязки используют свои собственные? О.о Даже инициализация контекста своя для каждой платформы, хотя давно уже есть glutin.

ух, действительно пахнет странно

Одно время назад пытался написать на расте игру и уперся в «ограничение, которое так и надо» — невозможность оперировать только абстракциями в расте. С постоянно выпрыгивающей руганью на Sized я бороться устал и все забросил. Теперь читаю ваш пост, и очень интересно посмотреть на внутренности того, что вы делаете, применимо к парадигмам Раста. Вы случайно не планируете если не опенсорсить движок, то хотя бы рассказать, как там что взаимосвязано.
Ура. Жду постов
пока вы пишете пост, можно быстрый вопрос — а чем вы отрисовываете графику? смотрел на glium — смущает, что это все-таки не чистый GL, и некоторые специфические фичи могут не поддерживаться. смотрел автогенеренные байндинги к GL — у них какой-то костыльный вызов.
Пока что glium'ом и рисуем.
По мне так у него хороший уровень абстракции — и от OpenGL далеко не уезжаем и некую безопасность имеем.
смотрел автогенеренные байндинги к GL — у них какой-то костыльный вызов.

А что такого костыльного gl-rs делает?

You must load the function pointers into their respective function pointers using the load_with function. You must supply a loader function from your context library
странно, почему это нельзя автоматизировать
так это кусок документации
Struct generator
.

в следующем абзаце:
Static generator

The static generator generates plain old bindings. You don't need to load the functions.


С ним всё хорошо, генерируются функции которые сами всё грузят как надо, автоматизация! :)

и этот самый Static generator и используется в glium.
Ага, нашел. Вот что меня тогда озадачило:
This generator should only be used only if the platform you are compiling for is guaranteed to support the requested API. Otherwise you will get a compilation error.

Это статический генератор. Имхо это верное решение, иначе какой смысл собирать, к примеру, поддержку OpenGL ES на Windows, если ее там нет?
Если понимать под абстракцией структуру неизвестного на этапе компиляции размера, реализующую определенный набор интерфейсов, то, как следует из её определения, работать с ней на стеке нельзя — только в куче. То есть, такие абстракции нужно оборачивать в Box (владеющий указатель на структуру, располагающуюся в куче).

Ошибки, связанные с Sized, скорее всего были вызваны именно попыткой поместить структуру неизвестного размера на стек или в массив.
Да это я знаю. Просто довольно тяжело пытаться играть в честный ооп, инкапсулируя имплементацию вообще всего и работать с трейтами, которые «не интерфейсы», и в этом случае данный факт очень хорошо чувствуется. А не в ооп играть — тяжко, глобально архитектурить без ооп я еще не умею.
Просто довольно тяжело пытаться играть в честный ооп, инкапсулируя имплементацию вообще всего и работать с трейтами, которые «не интерфейсы», и в этом случае данный факт очень хорошо чувствуется. А не в ооп играть — тяжко, глобально архитектурить без ооп я еще не умею.

А в чем разница с C++ в этой плоскости?
В C++ тоже нельзя создать объект класса с чисто виртуальными функциями,
на стеке, а потом на его место записать объект наследника. Да и вообще
с созданием объекта "класса с чисто виртуальными функциями" возникнут
некоторые проблемы. Придется как в Rust где-то (например в куче) хранить "конкретные" объекты и передавать куда нужно указатели на абстрактный класс.


И ничего живут же как-то, в ООП играют уже много лет.

А в чем разница с C++ в этой плоскости?

Я не знаю С++ на уровне, пригодном для коммерческой разработки, включая полиморфизм. Сравнивать с ним по этой причине не могу.
офигенный пост! Спасибо!
Понимаю, что могу отхватить за этот вопрос, но всё таки… Чем не подошёл С++? Возможно, я упустил обоснование выбора в пользу Rust где-то в статье — тогда заранее извиняюсь.

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

Ясно. Спасибо!..

статическая проверка корректности указателей во время компиляции


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

Речь о том, что нельзя забыть "проверить указатель". В том смысле, что нельзя его разыменовать без проверки.

в безопасном расте невозможно получить и соответственно разименовать невалидный указатель
http://rurust.github.io/rust_book_ru/src/ownership.html < — вот здесь описан этот механизм защищающий указатели
Спасибо. Почитал. Похоже на ссылки (и, в некотором роде, на умные указатели — однако в Rust они ещё и компайлтайм выходят) из С++ с некоторым ограничениями и синтаксическим сахаром (для понятия «время жизни»)…

Выглядит достаточно удобным. На плюсах для реализации подобного контроля кода пришлось бы статический анализатор подключать. А «время жизни» даже анализатор не смог бы контролировать. Разве что через какие-то хитрые аннотации в комментах (в комментах — так как плюсы с какого-то перепугу не поддерживают пользовательские аннотации), что не есть хорошо.
Всё так! действительно чем-то похоже на умные указатели, и действительно существуют только на уровне статического анализа при компиляции.
Еще эта штука с борроу-чекером классно помогает с многопоточностью (перевод) — гарантирует отсутствие data-races, а это тоже здорово :)
Смотрел, но довольно давно и не слишком внимательно.
Показалось, что фичей одинаково не хватает как для игрового гуя(хочется какую-то внешнюю вёрстку и возможности делать красивые эффекты) так и для тулзового гуя(я в основном сравнивал картинки с imgui и не особо внимательно смотрел на внутренности conrod).
http://arewegameyet.com/ — тематический ресурс
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории