Русский
Русский
English
Статистика
Реклама

Игростроение

Восстание игроков игра как миф

08.03.2021 18:14:03 | Автор: admin

Игра как миф

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

Может существовать (и существует) в некоторой части научной общественности достаточно предпосылок для того, чтобы не только рассуждать о мифической природе игр, но и вообще расценивать существование Игры как Миф; то есть не существует Игры как категории обладающей самостоятельной онтологией, существует лишь игра как: игра как форма коммуникативного взаимодействия, игра как процесс соблюдения комбинаций условий, игра как сходства игрового поведения человека и животного и т.д, где в таком случае игра есть символ по отношению к объекту, не являясь при этом самой собой, то есть Игрой; известно, что миф определяет мифическая отрешенность, что есть отрешенность фактов по ихидееот их обычного идейного состава и назначения[1], а то что принято под Игрой в таком случае - лишь поэтическое содержание в своей наитивной форме. Именно эта наличная для некоторой научной общественности глупость обязует привести онтологическую природу Игры, дабы с должной уверенностью расценивать игры как как миф, нивелирующий всю строгость соответствующих исследований.

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

То есть для того чтобы Игру превратить в Миф, требуется отойти от её герметической онтологии и наделить отдельным для неё смыслом. Очевидно, что для самой Игровой онтологии результаты исследований проявления её бытия в Мифе ничего для самого бытия не даст, разве что позволит исходить от обратного, и тогда мы получим, что игра как одновременно и относится, и не относится к Игре, явив тем самым категорию может. Тот факт, что Игра что-то может - сомнению не подвергается, однако само это потенциальное целеполагание и есть корень той отрешенности от герметической онтологии: Игра ни к чему не применима как к Игре, так как Игра по-Юнгеровски бесцельна, и для исследователя не будет абсолютно никакого толка составлять справочник об играх[3], как и о мифах.

Последнее известно постольку, поскольку за самой Игрой не кроется вопросов её человеческой природы, что, например, нельзя сказать о членораздельной речи. Не секретом является игривая природа некоторой части животных, как и не остаётся поэтому секретом посредственность вопросов о функциях как каждой игры по отдельности (так как энциклопедичность знания игр ничего не даёт кроме выявления морфем), так и функции игр вообще. Функция, как и цель не стоит в вопросах экзистенции Игры, так как осознание существования функции принадлежит человеческой природе. Никто не собирается здесь отрицать, что существуют игры, обладающие в своей эзотерической природе методологией к реализации задуманных функций, но это конечно при том условии, что эти функции реально задуманы, а не являются их следствием. Исследования игры часто оказываются далеки от своего предмета, когда они стремятся приписать игре какие-то мотивы или связать ее с какими-то целями[4].

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

Для всего вышесказанного пришлось нарушить завет[5] о не-рассуждении о Природе Игр, но без этого онтологическое основание Игры как бесцельной экзистенциальности невозможно, но я думаю и сам Юнгер понимал, что высказав о свойстве игровой бесцельности он вскрыл её онтологию. С этим основанием мы отбрасываем для игрока целеполагание как стимул, ведь не только сама Игра не обладает целью, но и для того чтобы субъекту превратиться в игрока достаточно лишь начать бесцельно экзистенциировать (а для этого не обязательно обладать тем разумом, что участвует в исследованиях бихевиористического, или символически-интеракционистического толка), что указывает нам на Игру как самодостаточную Саму для Себя и Саму по Себе, что прямо указывает на её субстанциональность. Сама же субстанция как свойство может выступать как точка отсчета, не заходящая за пределы самости, поэтому если ставить знак = между игрой и бесцельным экзистенциированием можно утверждать, что все что бесцельно существует само по себе выступает в качестве игрока, а само это существование есть Игра, соответственно. Поэтому в качестве стартового пункта остановимся на том, чем обладаем сейчас: Игра есть предельная (что очевидно) бесцельная экзистенция, обладающая предельной бесцельной экзистенциальностью, т.е. Она (по-Гегелевски) субстанциональна, если не (по-Аристотелевски) Природна[6]. Сохраняя такое онтологическое основание возможно следует внести правку в Юнгеровское высказывание об Игре как всяком движении, добавив к нему понятие бесцельности, а оригинальное высказывание отнести к понятию выраженной игры.

Игра выражена сама по себе за счёт собственной субстанциональности, и поэтому игроками становятся те, кто входит в область Её выражения самой для себя. В данном суждении мы не наделяем Игру мифом говоря о том, что жизнь это игра, или что ветер это часть природной игры, так как в самой природе суждения[7] предикат выражает субстанцию по отношению к субъекту, который при этом, очевидно, не наделяется инобытийным смыслом. Не будут являться также мифами и суждения, что Игра выражается через игры, или любая отдельно-взятая игра есть плод Выражения Игры. Именно за счет Выражения игроки Игры могут выступать творцами и участниками собственных игр, и само это Выражение до сих пор лежит за пределами тех стихийных[8] элементов природы Бесцельного Бытия, что согласно Юнгеру выступают в формах счастливого случая (выпадает без всякой цели), искусности (не имеющая цели легкость) и подражания (не имеющее цели отображение). Так как Игра есть Сама по Себе выражение т. к. Она субстанция, что тогда отличает Выражение Игры от Игры как Выражении Самой Себя вопрос на первый взгляд не из лёгких. Ключ к нахождению отличия скрывается в том, что Игра как субстанция единична, а Выражение Игры переходит во множество форм. То есть мы имеем абсолютную самодостаточную единицу и её бесконечное множество инвокаций как игр.

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

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

Как стало ясно, бесцельная экзистенциальность есть объективная категория, и цель есть граница этой объективной категории: она (бесцельная экзистенциальость) не может обладать целью, так как это в корне изменит её бесцельную экзистенцию. Но для природы целеполагание если не бессмысленно вообще, то как минимум необязательно для Выражении Себя, и свои производные выражения Смыслом. Сам же этот Смысл заложен в её онтологическом основании- бесцельном бытии. И поэтому любое бытие, в чьём Смысле заложена бесцельность именуется Игрой. И лишь постольку поскольку непринято рассуждать об играх никак иначе, кроме как о самодостаточной Бесцельной Деятельности, то что сейчас обычно понимается под играми имеет в себе мифологическую структуру превращения игрока в машину для (т.е. с целью) участия в играх. Игрок же для игры имеет весьма посредственный смысл, так как золото игры не в её участии, а в её форме, и ценность этого золота в Искусстве Выражения этой формы Бесцельного Экзистенциирования.

Поэтому какими бы ни были на первый взгляд общими игры человеческие и игры животных при всех их сходствах и корреляционных данных (брачные игры, обучающие игры и т.д.), вера во все эти статистические методы и расчёты вероятностей есть суеверие[9], ничего общего с реальными играми не имеющие; цель математики или её понятие есть величина[10], и бич несущий человечеству применение теории игр есть не творение игр, но программирование игроков в установленных величинах рационального поведения. И прежде чем перейти к основательной критике современных игр, стоит для начала указать на феномен художественных форм искусства бесцельного экзистенциирования.

[1] А.Ф. Лосев: Диалектика Мифа. Глава 8 Принцип мифической отрешенности.

[2] Там же.

[3] Ф.Г. Юнгер: Игры и ключ к их значению, стр.36

[4] Ф.Г. Юнгер: Игры и ключ к их значению, стр. 266

[5] Ф.Г. Юнгер: Игры и ключ к их значению, стр.42

[6] Г.В.Ф. Гегель природу Аристотеля отождествляет с пониманием субъекта.

[7] Г.В.Ф. Гегель: Феноменология Духа, стр.38

[8] Ф.Г. Юнгер: Игры и ключ к их значению, стр.313

[9] Ф.Г. Юнгер: Игры и ключ к их значению, стр.76

[10] Г.В.Ф. Гегель: Феноменология Духа, стр.28

Подробнее..

Представляем Owlcat Mono Profiler для Unity

04.12.2020 12:06:11 | Автор: admin

Официальная часть мероприятия

Добрый день. Я работаю программистом в компании Owlcat Games, которая выпустила одну из самых успешных российских компьютерных RPG Pathfinder: Kingmaker и сейчас работает над её продолжением, Pathfinder: Wrath of the Righteous. В ходе портирования первой игры нашей студии на консоли, мы столкнулись с проблемой поиска утечек памяти. Штатные инструменты движка Unity и целевых платформ оказались по разным причинам не слишком удобны для борьбы с утечками, и поэтому мы решили написать свой инструмент, о котором я и расскажу ниже.

Owlcat Mono Profiler предназначен для исследования использования памяти Mono в играх на движке Unity. Он доступен всем желающим в виде собранных бинарных файлов (под Windows) и исходного кода на Github. В отличие от встроенного профайлера Unity, а также пакета Memory Profiler, он не требует снятия снимков состояния памяти, а производит постоянный мониторинг Mono-кучи, что позволяет выявлять не только утечки, но и пики аллокаций, и избыточные повторяющиеся аллокации. По сравнению с платформо-специфичными инструментами, такими как Memory Analyzer для PS4, он корректно отображает события, происходящие с памятью, управляемой сборщиком мусора.

На этом покончим с формальностями, и перейдём к cool story.

Фатальный недостаток всех прочих инструментов

Началось всё с того, что мы выяснили, что память в нашей игре подтекает. На PC это не было проблемой, поскольку течёт она не то чтобы водопадом, да и памяти даже на слабых машинах в наше время будет поболее, чем у PlayStation 4 или XBox One. Плюс, Windows, когда кончается память, начинает скидывать лишнее в своп, а консоли - просто убивают твоё приложение, и иди, разбирайся, где накосячил.

Встроенные инструменты Unity пришлось отмести практически сразу: в Unity 2018.4 они с нашей игрой фактически не работали (снятие одного снимка состояния памяти могло занять 8+ часов, а на PlayStation мне ни разу не удалось его дождаться в принципе). В 2019.x стало сильно лучше, но перейти на неё мы не могли - смена мажорной версии движка в Unity ломает слишком многое.

В комплект инструментов для PlayStation 4 входит совершенно потрясающий Memory Analyzer. Серьёзно, это один из лучших инструментов для анализа потребление памяти, какие я только видел (хотя и не лишённый некоторых мелких недостатков). Уже одна только возможность помечать любые функции с подходящей сигнатурой как alloc/realloc/free делает его невероятно полезным для любой игры, использующей собственные аллокаторы, memory pool'ы и т.п.

Но есть проблема. Дело в том, что Mono, в том виде, в каком его используют в Юнити, содержит в себе видавший виды сборщик мусора BoehmGC. Это проверенный временем проект, но к сожалению он написан таким образом, что во многом представляет из себя помесь чёрного ящика и чёрной дыры, в которую можно что-то засунуть, но нельзя достать. В частности, он не предоставляет никакого способа узнать о моменте удаления объекта.

Почему сложно написать профайлер памяти для Unity

А теперь давайте сделаем шаг назад и посмотрим, как вообще работает сборщик мусора. Я до поступления в команду Owlcat Games работал, в основном, с C++, поэтому чисто теоретически про сборку мусора что-то знал, но на практике с ней не сталкивался, и имел, как потом выяснилось, в корне неверные представления о том, как этот зверь устроен. Если вы в этой области собаку съели, то дальнейшие мои объяснения вам покажутся чересчур упрощёнными и может быть даже в чём-то ошибочными, но надеюсь они подойдут для объяснения той простой мысли, что написать профайлер памяти для языка с GC - это вам не два байта переслать.

Итак, что делает сборщик мусора? Он берёт себе у системы кусок памяти И никогда его не возвращает (во всяком случае, именно так ведёт себя BoehmGC на PS4). В этом куске памяти, он по запросу пользователя выделяет маленькие кусочки под конкретные объекты - там тоже не всё так просто, но это не важно. Важно что факт аллокации памяти отследить очень просто - есть несколько функций, которые прямо так и называются, gc_malloc_что_нибудь. А вот факт деаллокации памяти отследить слегка сложнее. Это в C++ кто-то должен сказать объекту "умри". Тут же про него просто "забывают", то есть, перестают на него ссылаться. Конечно, сборщик мусора не следит за всеми записями в память, чтобы заметить, что последняя ссылка на объект протухла. Вместо этого, раз-в-сколько-то времени (на самом деле - обычно когда для очередной аллокации не хватает памяти) он говорит "так, всем стоять, сейчас я разберусь, кто тут живой, а кто мёртвый", и отправляется шерстить всю выделенную памяти в поисках ссылок на объекты. В конце этого процесса, если есть какие-то объекты, на которые он ссылок не нашёл, их-то он и удаляет, а точнее - помечает их память как свободную и доступную для выделения.

Всё выше сказанное плюс особенности BoehmGC означает две вещи: во-первых, факт смерти объекта неплохо так (порой на десятки секунд) удалён от момента потери последней ссылки на него, и во-вторых, хрен нам, а не событие "объект удалён". Сколько я не пялился в код BoehmGC, так мне и не удалось в моём скудоумии прозреть, где же, собственно, тот волшебный момент, куда можно было бы вставить какую-то закладку, которая бы сообщила наружу, что память, которую занимал объект X, более ему не принадлежит, то есть, он мёртв. Впрочем, даже если бы я его нашёл, вряд ли бы мне это помогло, потому что по условиям задачи менять код BoehmGC у нас возможности не было - на PlayStation его просто невозможно скомпилировать самому, да и на остальных платформах это то ещё приключение (потому что компилировать придётся не только сам BoehmGC, но и Mono).

Бьёмся головой в стену.

Следующей мыслью, пришедшей мне в голову, было добавить всем вообще аллоцируемым объектам финалайзеры. Финалайзер - это такая функция, которая как раз обязательно вызывается, когда объект удаляется, вроде деструктора в C++. Но и на этом пути меня не ждала победа: да, в рамках il2cpp, имеющего открытый исходный код, я мог вставить свой костыль, но это нельзя было делать оголтело, ведь у объекта УЖЕ мог быть финалайзер, а значит надо было его как-то извлекать, запоминать и подменять своим Наверное, если копать в этом направлении дольше, может что-то и получилось бы, но сама идея менять исходный код кусков Unity мне не нравилась, не говоря уже о том, что это решение не заработало бы на PC, где мы не используем il2cpp во имя лёгкости моддинга игры.

Дальше я отправился в Гугл, искать, а как вообще люди профилируют память в Mono? Ответ нашёлся на первой странице Гугла, в официальной документации. Вот только в версии Mono, используемой Unity, описанный там встроенный профайлер был благополучно выпилен. Кроме того, поиск так же показал, что почти все средства анализа логов, снятых при помощи встроенного профайлера, заброшены, устарели или недописаны, так что особой надежды на них не было, даже если бы мне удалось как-то вернуть эту функциональность (например, пересобрав Mono для Unity - что, правда, не сработало бы на PlayStation!).

Мы пойдём другим путём!

Однако, бродя по дебрям сети, я наткнулся на Heap-Prof, давно неактуальный и заброшенный профайлер памяти для Mono, из которого, однако, мне удалось почерпнуть интересную идею. Идея заключалась в том, чтобы тупо повторять всю работу, которую делает реальный сборщик мусора:

  • Регистрировать аллокации, когда они происходят, создавать событие "объект создан".

  • Ловить события сборки мусора (типа "сборка мусора завершена") и в этот момент проверять, какие из наших объектов всё ещё живы. Для всех, кто не жив - создавать событие "объект удалён".

Довольно быстро, я перенёс и осовременил код heap-prof в dll, которую подгрузил плагином к Юнити, достал при помощи GetProcAddress функции Mono, позволяющие всё это проделать, и И игра упала. В функции mono_object_is_alive. Попытки понять, от чего такое происходит, и как вообще эта функция работает, привели меня к письму одного из авторов Mono, Massimiliano Mantione, опубликованному в почтовой рассылке Mono-dev в 2009 году. Во сием послании, он в точности описывал мои проблемы с heap-prof, и в частности писал, "The problem is that this is not reliable: "mono_object_is_alive" was not meant to be a public function. And in fact sometimes the heap snapshots are wrong (or the profiler crashes).". К сожалению, в качестве решения он предлагал улучшить API для профайлера в НОВОМ сборщике мусора, SGen, на который Unity в своей версии Mono так никогда и не перешли

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

Тут надо сделать очередное небольшое отступление, и рассказать о том, как рассуждал Шульц как сборщик мусора, собственно, ищет ссылки на объекты. Опять же, в ОЧЕНЬ упрощённом виде. Ищет он их тупо - берёт память какого-нибудь объекта, и прямо по ней идёт и смотрит - вот это значение похоже на адрес в куче? Есть у нас объект с таким адресом вообще? Если на оба вопроса "да" - то это ссылка на объект, и этот объект смело можно помечать как живой. Острые умом подметят, что если эдак пройтись по всей куче итеративно несколько раз - не останется ни одного объекта (например, если в куче всего два объекта, A и B, A ссылается на B, то мы сначала удалим A - потому что на него никто не ссылается, а на следующей итерации удалим и B, потому что теперь на него тоже никто не ссылается). Для этого у сборщика мусора есть корневые объекты, которые удалять обычным образом нельзя, и вот от них уже идут ссылки на всех остальных.

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

"Я вас настиг! Какой я молодец"

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

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

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

Помимо прочих достоинств, наш профайлер умеет профайлить релизные билды игры, и даже без необходимости заранее встраивать плагин в сборку (можно и чужие игры профайлить, если у вас возникло желание помочь авторам). Достаточно только иметь PDB файл от нужной версии Unity Player: он нужен для того, чтобы достать адреса некоторых функций, которые нужно перехватить, в частности, для того, чтобы вовремя запустить профайлер, а также для получения событий об окончании кадра (события для удобства группируются по кадрам, а не по времени). К сожалению, Unity не предоставляет даже графическим плагинам возможности узнать о конце кадра другим способом, так что пришлось взять в руки Microsoft Detours и лезть в недра.

Есть у выбранного подхода и недостатки. Профайлер довольно заметно замедляет игру, процентов на 20 в обычных кадрах, а в момент сборки мусора может подвесить её даже на 5-10 секунд (в зависимости от количества объектов). Также, для профайлера требуется довольно много памяти на той машине, где, собственно, запущена игра: на ~2 миллиона аллокаций нужно ~200Mb памяти. Для базы клиента/UI, может потребоваться до нескольких гигабайт памяти, что представляется несущественным ограничением, так как в крайнем случае, можно запускать клиент/UI профайлера на другой машине (он соединяется с самим профайлером по сети).

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

Текущая версия профайлера имеет интерфейс, написанный на Qt5, и теоретически должна быть относительно легко портируема на другие операционные системы (это в наших планах, но не в приоритете, так как основная часть разработчиков игр, всё-таки, работает под операционной системой Microsoft). В качестве БД для хранения событий, используется SQLite с временными (частично находящимися в памяти) базами, но есть идеи о переходе на memory mapped database для ещё большей скорости. Я обдумывал возможность интеграции профайлера в саму Unity, но это представляется не идеальным решением, так как иногда хочется попрофайлить игру в редакторе, не собирая билдов (когда пробуешь разные варианты исправлений, например), а в этом случае, профайлер, встроенный в редактор и потому также производящий аллокации managed памяти - очень плохая идея.

Дальнейшие планы

Профайлер открыт для свободного использования всеми желающими. Я надеюсь, что он окажется полезным кому-то кроме нашей компании. Несомненно, найдутся в нём и ошибки, которые надо исправлять, и возможные улучшения интерфейса и функционала. Жду ваших предложений (и пулл-риквестов!) на Гитхабе. Я надеюсь, что эта программа станет первой частью нашего инструментария для отладки игр на Unity, Owlcat Grooming Toolkit. В отдалённых планах есть так же CPU профайлер с открытым исходным кодом, который мог бы стать бесплатной альтернативой dotTrace, которую можно было бы раздавать игрокам для диагностики без зазрения совести.

Подробнее..

Tantramantra и магия проектирования

03.04.2021 22:15:26 | Автор: admin
Доброго весеннего дня!
Во время разработки различных механик и прочего интерактива для компьютерных игр, складываются различные схемы-рецепты для реализации требуемого функционала. Большая их часть не привязана к конкретному используемому движку/языку. О некоторых из них я расскажу на примере одного из своих проектов с биомашинками.



Тантрамантра



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







Проектирование игровых механизмов



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

Вопросы вида почему же Марио разбивает головой кирпичи это совершенно не то, что волнует играющего в Supermario. Он планирует в какую трубу прыгнуть, как разбить блок и успеть схватить гриб, чем бы убить назойливое облачко. По сути это решение различных задач, представленных в виде символов и внутриигровых взаимосвязей. Символы, конечно, запускают ассоциации, поэтому попутно можно обсудить с окружающими кирпичи, водопроводчиков, трубы с мухоловками и прочий происходящий психодел (которого на самом то деле и не происходит, просто наверное это более отвлечённая и интересная тема, чем обсуждать какие-то скучные бытовые вещи).

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

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

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

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

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

Грибы

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

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


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


В основной части скрипта происходит следующее: в инициализации на триггер вешается функция Enter. В основном цикле Update накручивается счётчик, если гриб в состоянии притвориться мёртвым. По истечении данного счётчика гриб меняет состояние на жив и снова ждёт когда его переедут. В функции Enter, собственно, гриб временно исчезает и меняет состояние на мёртв.
Чтобы всё выглядело ещё лучше можно сначала показать недавно умерший гриб в уменьшенном состоянии, не активируя сам триггер, после чего понемногу модельку гриба увеличивать, и только потом уже включать триггер.


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

Терминаторы

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

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


А вот как эти враги устроены пара сфер и пустышка-прицел, в которую спавнятся выстрелы


Весь код приводить не буду, ограничимся разбором параметров. Пара счётчиков для отслеживания пауз между выстрелами и рейкастами. Хитпоинты. Флаги состояний, для определения, когда нужно двигаться прямо (потому что рейкаст не касается земли) и когда нужно на некоторое время переключиться в состояние взлёта над землёй. В инициализации рассчитывается случайная прибавка к скорости, чтоб разные враги двигались с немного отличающимися скоростями и реже наползали друг на друга.


Оружие

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

Оружие нужно было: а) поднять, б) стрелять. Это если смотреть с позиции игрока. Ну а с точки зрения разработчика: а) как-то устанавливать коллизию оружия с машинкой, б) решить, как именно отображать то, что оружие получено в) определить правила по которым оружие используется. Как видно, сами выстрелы таким образом получились даже не в приоритете. Во многом потому, что сам по себе спавн машинкой направленно движущихся объектов уже был заготовлен и оставалось его только прицепить к реализации оружия.


Точка подбора оружия тоже использует WorldTrigger для определения столкновения


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

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


NodePet объект, изображающий пушку


Код NodePet. В качестве точки привязки, за которой он будет следовать, указана пустышка-прицел, висящая на машинке. А Rotator это другая пустышка, уже в центре самой пушки, которая копирует на себя поворот того прицела, чтобы пушка смотрела в нужную сторону (в качестве бонуса это даёт эффект вращения пушки вокруг своей оси, когда машинка двигается).
Здесь как раз реализован принцип отслеживания координат пушка начинает смещаться, если машинка удалилась от неё на определённое малое расстояние. Поначалу отслеживалось отклонение только по осям X и Y, а потом я дописал и Z для большей точности.




Выстрелы

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

Работают эти выстрелы немного по-разному.


Фрагмент скрипта вражеских выстрелов. Они появляются и начинают лететь в том направлении, куда смотрел терминатор (то есть на игрока). Производить дополнительные действия выстрел начинает не сразу, а после небольшой задержки (reactionTimer) простой способ избежать каких-то нежелательных столкновений в точке его появления.
После задержки выстрел начинает анализировать пройденные отрезки на предмет пересечений, и если там что-то нашлось, то уничтожается, проигрывая эффект.
Если у этого чего-то имелось RigidBody, то выстрел применит туда импульс.
А если это ещё и машинка, то выстрел находит на ней скрипт и вызывает там функцию потери хитпоинтов.
Так как вражеские выстрелы отслеживают пересечения с большей частью геометрии, то они часто могут попасть в какую-то визуальную часть машинки, не достигнув её ядра. Таким образом получается, что часть выстрелов словно не пробивают броню.


Демоверсия



Ниже видеонарезка игрового процесса из свежей версии прототипа 01_02



Архив с демкой весит 714Мб. Запускается она на 64-битной Windows и доступна для скачивания на страничке itch.io (используется Unigine engine, поэтому системные требования не самые малые):

https://thenonsense.itch.io/tantramantra

Подробнее..

Демо-версии Невангеров для Unigine и Godot

19.10.2020 22:04:09 | Автор: admin
Альтернативные прототипы с биомашинками (и не только био-), которые собрал за время знакомства с игровыми движками Unigine 2 и Godot 3.




Unigine engine



Начнём с версии для Unigine. Используется версия 2.11, вышедшая этой весной, начиная с которой в движке появилась бесплатная лицензия. На данный момент вышла 2.12 и скоро ожидается 2.13.

Что в общем стоит знать про Unigine это томский игровой движок, часто используемый для бенчмарков и симуляций. На нём в разные годы вышли такие игры как Oil Rush, Cradle, и вот, например, относительно недавняя ммо Dual Universe.
Внутри применяется довольно много интересных и перспективных решений, рендерит достаточно красивую картинку и может довольно сильно приглянуться художникам, особенно если те моделят в отдельном 3д-пакете, а не средствами самого движка.

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

В качестве инструмента для игрового разработчика здесь в принципе применим опыт использования C# в Unity, хотя в Unigine нет такого же многообразия готовых компонентных решений. Тем не менее, какие-то базовые вещи реализованы, а документация поможет написать остальное. С++ тоже никуда не делся.

Для мобильной платформы движок пока не подойдёт, как и для разработки без программирования (хотя планируется развивать его и в этих направлениях). Требования к железу на уровне запросов Unreal, минимальный вес файла приложения довольно большой. Зато красиво и неплохо оптимизировано.

Но вернёмся к игровому прототипу. В версии для Unigine основные сложности были связаны с визуальным конструированием физики для машинки, потому как в документации предлагается делать всё это вслепую, через код, к тому же всевозможные физические настройки разбросаны по разным местам редактора и сам пайплайн визуальной сборки не описан. То есть не было банального готового примера, который можно было бы модифицировать, не погружаясь во все нюансы. В 2.12 вроде появилось демо с копающим землю трактором, но, возможно, он опять собирается кодом, не смотрел этот момент.

Как бы то ни было, машинку я более менее собрал, ориентируясь на документацию. О чём ранее писал соответствующую статью: Как я собирал физику колёс в Unigine

Что касается геймплея, в Unigine, в отличие от Unity и Godot, например, оказалось довольно просто переключать физику машинки на лету, не только визуал, но и расположение/размер колёс. Без придумывания дополнительных трюков для того, чтобы не провалиться сквозь пол, и без пересоздания модели. Хотя, существует некоторый шанс провалиться в текстуры, но совершенно в иных ситуациях, а не в момент смены машинки.

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

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

Другая удручающая вещь, простые анимации, записанные на внутренний инструмент трекер. Да, он по-своему мощный, но какой-то слишком квадратно-гнездовой в использовании. Мало этого проиграть записанную таким образом анимацию можно только используя устаревший язык UnigineScript. Это в то время как в Unity или Godot можно заанимировать буквально всё вокруг по периметру. Да, можно импортировать анимацию костей, но это немного другое.
Если, опять же, взглянуть на это с другой стороны, то движок всё-таки больше ориентирован на физические симуляци и взаимодействия, так почему бы этим не воспользоваться вместо запекания каких-то там предустановленных анимаций то есть делать какие-то эмиттеры, переключатели, взаимодействующие конструкции, применять силы, использовать гравитацию и так далее. Так что без внутреннего аниматора можно обойтись, но если бы он был нормально реализован, то это тоже большое дело хотя бы даже в плане режиссуры в несколько кликов записать пролёт камеры по сцене со всякими интерактивными элементами, и вот тебе уже готовый фильм. Тем более, при таких возможностях для кинематографичной картинки.

Что касается своего проекта на данный момент после нескольких итераций я наконец собрал и выложил более менее цельную демку, которую можно тестировать.



Архив для Win64 можно скачать здесь (вес 687Мб): DROPBOX
или на страничке itch.io: NEWANGERS
в распакованном виде занимает 3Gb

Что тут есть:

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

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

* Многие объекты уровня проницаемы, но у некоторых есть коллайдеры и сами уровни более менее окружены блокирующими стенками.

* Машинка в основном управляется кнопками WASD. Также можно стрейфиться по Q и E. Прыгать на пробел, или, наоборот, сильнее устремляться к земле нажимая R. По Tab машинку можно крутить, чтобы, например, перевернуться и встать на колёса.
Стрейфам и прыжкам не установлены лимиты, то есть во время прыжка можно прыгать дальше и так далее.

* Кнопки 1,2,3,4,5,6,7 переключают разные машинки. Колесом мыши можно слегка зумить камеру.

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

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

* P выход из игры, L перезагрузка с откатом на стартовый уровень

Более ранние исходники этого прототипа знакомый выложил на своей страничке вместе с некоторыми правками физики колёс первоначальной версии: GITLAB

Godot engine



Переходим к следующему движку в нашем списке. Опенсурсное компактное решение с огромными возможностями (Blender от мира игровых движков), но, опять же, пока уступающий тому же Unity в плане многообразия готовых компонентов. Хотя, различных неофициальных решений, а также примеров с исходниками для Годо уже написано довольно много и благодаря относительной простоте/быстроте имплементации нового функционала, не сказать, чтобы это было какой-то проблемой на данный момент.

У Годо больше репутация 2д-движка, благодаря многообразию проработанных инструментов именно для 2д, но они являются дополнительным плюсом для 3д куда проще делать игровой UI. Ещё проще чем в Unity, как по мне. На текущий момент Годо в своём развитии дошёл до стабильной 3.2.3 версии (но все ждут 4 из за вулкана, оптимизаций и так далее. шаткие сборки четвёрки, кстати, уже можно пробовать хотя бы оценить картинку).

Движок не требует мощного железа для 3д-графики и выдаёт вполне приличную картинку. Готовых трёхмерных инструментов не огромное количество, но реализованы как раз одни из самых нужных, полезных и универсальных. Примерно то же касается и оптимизаций. Например, в движке реализован обычный frustrum culling, отсекающий геометрию вне зоны видимости камеры. Occlusion culling (чтобы не считать закрытые стенами объекты) реализацию придётся придумывать самостоятельно (что не так уж сложно, особенно в каких-то точечных местах, да и не в каждой игре нужно). Также из коробки в движке нет батчинга геометрии (правда для gles2 частично есть) и террейна, но это не такая уж проблема, просто потребуется что-то оптимизировать вручную сшивать какие-то меши вместе, бить геометрию на мелкие части или использовать чанки и так далее. Можно подыскать какую-то реализацию в местном небольшом сторе, например, добавить в свой проект готовое решение для террейна.

Интерфейс движка, кстати, довольно продуманный и кастомизируемый (хотя есть некоторые негибкие элементы). Пользоваться им в целом удобно. Поддерживаемых языков достаточно, для разного уровня погружения. Тут и C++ и C# и довольно удобный внутренний GDScript, который запускается прямо внутри редактора, не требуя запуска отдельной среды. Визуальный скриптинг тоже присутствует, так что без знания программирования в Годо тоже вполне можно жить какую-то минимальную логику сконструировать, что-то заанимировать (в Godot есть простой и классный инструмент для записи анимаций).

Малый вес приложения, мультиплатформенность, быстрота разработки, простота имплементации различных сторонних решений тоже немаловажные плюсы движка. Есть два варианта рендера gles2 и gles3, оба поддерживают 3д, но в первом оно попроще и в целом он больше подходит для 2д и мобилок. Gles3 даёт более продвинутый уровень графики, какая-то часть мобильных устройств его тоже поддерживает.

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

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

В Годо есть интересные инструменты, вроде CGS-объектов и мультимеша. Подробнее про особенности их использования я писал в статье: Godot, 1000 мелочей

Прототип Невангеров на этом движке получил отдельное название Wild Engines. В целом у меня получается как бы семейство сходных проектов, объединённых концепцией странных машинок путешествующих по странным мирам. И в качестве рабочего собирательного названия я их привык именовать Невангерами, пока не придумается более конкретное наименование. У Godot прототипа теперь появилось своё название, у приостановленной на версии 0.9 Unity версии (с которой всё и началось) тоже появилось другое название, но до этого дойдёт дело потом, если появится время к ней вернуться.

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

Попутно стал собирать уровень из платформ, состоящих из маленьких блоков, пробуя различные подходы к оптимизации и замеряя производительность. Оптимизации оптимизациями, но в какой-то момент я уже настолько заполнил видимую на камеру область геометрией, что редактор перестал тянуть всю запущенную сцену, вываливась с ошибками. Что исправилось включением большего количества памяти в настройках. Тогда я сильнее увёл генерацию платформ в код, оставив на сцене только упрощённые габаритные блоки с идентификаторами, которые сами подгружали в себя нужную платформу при старте игры. После чего откатил количество используемой памяти к меньшему значению и уже без проблем увеличил уровень ещё в несколько раз. К тому же при такой реализации всегда остаётся вариант переиспользования уже подгруженных платформ, перемещая их в другие места уровня, когда машинка направляется в ту сторону, чтобы иметь возможность рисовать ими пространство уровня практически до бесконечности при тех же ресурсах и без переходов.
Примерно похожим образом я потом собрал наброски похожего уровня в Unigine, только там редактор сразу тянет всю сцену без надобности подгружать платформы в блоки через код (но для Unigine и компьютер используется куда более мощный).

В итоге в демо версии Wild Engines есть 4 машинки, одну из которых нужно выбрать для старта, и два небольших уровня (Level A и Level B). Пара ранних карт тоже осталась (Levels 0 и 1), но они ещё более тестовые и ландшафт там неоптимизирован.



В меню можно включить/выключить полноэкранный режим и тени.
Кнопки 1, 2 и 3 меняют позицию камеры. Мышь нацеливает и поворачивает камеру, тем сильнее, чем дальше курсор от центра.
WASD перемещение. PgDown прыжок. Q случайный импульс.
Левая кнопка мыши выстрел.
По Enter появляется подсказка об управлении и кнопка возврата в основное меню, где можно поменять машинку/уровень.

Win64 версия (42 Mb): DROPBOX wildengines_x64
Linux версия (44 Mb): DROPBOX wildengines_linux

Бонус



А вот один из недавно появившихся новых мехосов, Некромант:

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

Ещё тут завалялся один старый картридж как по вашему, клоны каких восьмибитных игр могли скрываться под таким названием на китайском картридже, будь Вангеры всемирно известной франшизой в те далёкие времена?

Подробнее..

Биом, демоверсия игры на Godot

18.12.2020 20:18:20 | Автор: admin
Собрал небольшую демку для win и linux. Этот экспериментальный прототип фокусируется на игре с видом сверху, и реализации системы бесконечного уровня в движке Godot. Биомашинки в комплекте.


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

Архитектура уровня



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

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


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

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

После тестов дополнительно пришлось исправить такой нюанс, что триггеры участков плотно примыкают друг к другу и могла произойти ситуация, когда машинка только касается нового триггера, не выходя из старого (то есть зона перекладывается новым триггером, а старый не был активирован). Этот момент был исправлен тем, что триггеры стали учитывать и вход и выход машинки, перекладываясь только при выходе из зоны триггера и только тогда, когда выход случился не из той же самой зоны, которой только что коснулись (устраняя тем самым проблему касаний). В целом, использование триггеров зон в Godot это, разумеется, далеко не единственный способ реализации подобной перекладки уровня, но один из относительно простых.

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


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


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

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


В скрипте каждой плитки выставлен ID, по которому она подцепит нужный фрагмент.

Игра



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





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


Видеонарезка с моментами геймплея демо-версии. Используемый игровой движок Godot engine 3.2.3, рендер gles3

Скачать демо для своей ОС (windows 64 .exe, linux .x86_64) можно на страничке itch.io (вес архива около 60Мб):
https://thenonsense.itch.io/biome

Подсказки по управлению показываются в игре при нажатии кнопки Enter, внутри открывающегося инвентаря.

WASD передвижение
мышь частичное прицеливание (и влияние на автокамеру)
Пробел прыжок
Левая кнопка мыши выстрел
Q,E стрейф
1 включить/выключить автокамеру
2,3 приблизить/отдалить камеру
PgUp случайный импульс

Также оставлены специальные опции для тестирования, которых в норме не должно быть у игрока (отмечены красным во внутриигровой подсказке):

4 большая степень приближения камеры
Home превратиться в душу либо в базовую машинку
End создать врага
PgDown создать живое оружие

Бонус


Недавно появившийся в прототипе летающий транспорт веретенолёт.

Также есть видео из другого прототипа на Unigine engine, с более ранней версией этой биомашинки:
Подробнее..

Чего не хватает современным шутерам?

03.08.2020 08:09:56 | Автор: admin
Маленький дисклеймер
Заметка нашлась в записках, относящихся к той самой, ещё весной обещанной тут статье, которая, к сожалению всё ещё не готова, хотя на дворе почти осень.
На сегодняшний день статья без иллюстраций выглядит так, кроме того удалось определиться с её конечным названием:

image
image
Одной очень простой, но важной вещи!
Случайно генерируемых на каждый матч (не раунд) локаций.
Именно это добавит киберспортивным соревнованиям азарта, предъявит к спортсменам более высокие требования и подогреет зрительский интерес. Тем более, что реализовать это сегодня с технической точки зрения не сложно!
Конкретно для спортсменов повысится требование к навыку спортивного ориентирования.
Остаётся только дать командам 10-15 минут до начала матча на ознакомление с зоной!

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

Recovery mode Чего не хватает современным шутерам?

03.08.2020 10:14:39 | Автор: admin
Маленький дисклеймер
Заметка нашлась почему-то в записках, относящихся к той самой, ещё весной обещанной тут статье, которая, к сожалению всё ещё не готова, хотя на дворе почти осень.
На сегодняшний день статья без иллюстраций выглядит так, кроме того удалось определиться с её конечным названием:

image
image
Одной очень простой, но важной вещи!
Случайно генерируемых на каждый матч (не раунд) локаций.
Именно это добавит киберспортивным соревнованиям азарта, предъявит к спортсменам более высокие требования и подогреет зрительский интерес. Тем более, что реализовать это сегодня с технической точки зрения не сложно!
Конкретно для спортсменов повысится требование к навыку спортивного ориентирования.
Остаётся только дать командам 10-15 минут до начала матча на ознакомление с зоной!
В киберспортивном плане обсуждение новой карты игроками могло бы стать интереснейшей частью трансляции! Только мат запикать, пустив поток с задержкой в пару минут

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

Recovery mode Восстание игроков замечание об однопользовательских играх

25.03.2021 16:19:55 | Автор: admin

Всем тем, кто не хочет читать: игра не игра, когда она выступает против игрока, то есть наделяется какой-то определённой целью выступать против или за. Понятие "уровня" и "lvl", стоит только его ввести в концепт игры - убивает саму игру, превращая её в обыкновенный спорт, порождающий спидранерство. Но если на территории вашего уровня существует множество некоторых песочных мелочей, которые позволяют не следовать главной "цели", - аркадная игра превращается в отыгрыш собственной личности в пределах закодированного пространства и тех "фич", за счёт которых сие можно производить (например "кулинарии"). Если же изначально игра делается "ролевой", вы опять-таки игру наделяете "самоцелью", а потому разрушаете её бесцельность, и поэтому сталкиваетесь с тем явлением, что именуется манчикизмом. Манчкизм что в RPG, будь они настольные или в киберпространстве, что в MMORPG производится строго по той причине, что игрока обязывают соблюдать эти самые условия прохождений "сюжета" и "уровней", игнорируя тот факт, что сам по себе игрок не хочет участвовать в вашем спектакле, а хочет уйти в лес. Дайте ему возможность погулять в лесу больше, чем спускаться в ваше подзмелье. Ответ хейтерам.

Его (тип игрока*) нельзя изучить, используя методы социологии, потому что он не связан строго ни с каким определённым социумом такой игрок не есть ни человек пользы, приобретения, профессии, труда[1]. Здесь об этом стоит возразить следующим образом: игрок есть адаптирующийся субъект в условии бесцельного экзистенциирования; играть - адаптироваться в условии бесцельного экзистенциирования соответственно. И только на этом моменте понимания "игрока" как адаптатора могут вступить в полемику Юнгеровские счастливый случай, искусность и подражание, к которым сводятся все игры; с того момента как процесс адаптации завершается, то завершается и игра. Но при этом это не будет означать что игра завершится благоприятным или неблагоприятным исходом, завершение игры может произойти и посредством её прервания, ведь сама из себя игра вовсе и не обязана к чему-либо приводить.

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

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

Само воззрение о тождественности рационального и игрового поведений нивелируется, и не потому что противник определяется неизвестностью (за счёт тайного знания механик) объективного оценивания сложности игроком, сколько потому, что игра для игрока таким образом может резко поиметь цель; цель победить высокий уровень сложности. Мало того, но с того момента как игрок остаётся один на один с уровневой системой, его противником начинает выступать не игрок, а сама игра, в связи с чем игра в те же шахматы симулируется, как и симулируется игра. Её бесцельное онтологическое основание становится лишь иллюзорной видимостью, ведь теперь она не существует сама по себе, а наделяется вполне конкретной целью: создавать иллюзию реального противника за счёт запрограммированного рационального поведения.

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

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

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

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

Из всего этого можно вывести тезис: киберпространственные игры есть игры только ролевые для одиночного игрока, или спортивные игры для (что очевидно) спортсменов. То же, что совмещает спорт и ролевую игру в киберпространстве не есть массовая многопользовательская ролевая онлайн- игра, поскольку мморпг лишь иллюзорно обладает спортивными элементами командного соперничества: ММОРПГ не заканчивается НИКОГДА, в ней НЕЛЬЗЯ ни победить, ни проиграть, и собственно умереть в ней нельзя. ММОРПГ является в своей сути ни киберспортом, и не киберролеплеем, - это есть одно из самых настоящих порождений киберигровой мифологии.


[1] Ф.Г. Юнгер: Игры и ключ к их значению, стр.68

[2] Г.В.Ф. Гегель: Феноменология Духа, стр.28

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru