Godot — это не новая Unity. Анатомия вызова API в Godot
Эта статья выросла из бесед с Godot-разработчиками. Они заботятся о том, чтобы поднимаемые проблемы решались, и стремятся улучшать ситуацию. Определённо, в Godot грядут серьёзные изменения, но сама платформа пока находится на ранней стадии развития. Поэтому сложно говорить с уверенностью, что именно изменится и в какой степени. На самом деле, я полагаю, что Godot ждёт самое светлое будущее.
Я, как и многие другие, в последнее время активно ищу «новую Unity». У Godot есть потенциал, особенно если на платформу удастся привлечь талантливых разработчиков, которые обеспечили бы её стремительное развитие. Это одна из самых крутых черт свободного ПО. Но здесь есть серьёзная проблема, сдерживающая развитие Godot: связующий уровень, проложенный между кодом движка и кодом геймплея, структурно рассчитан именно на медленную работу. Такое устройство кода очень сложно исправить, не снося всю конструкцию до основания и не перестраивая API целиком с нуля.
На Godot уже были разработаны некоторые успешные игры, поэтому, конечно же, вышеперечисленные факторы не являются непреодолимыми. Но в Unity в течение последних пяти лет ведётся работа по ускорению работы сценариев, и ради этого было запущено несколько проектов один другого страннее: создано два собственных компилятора, написаны математические ОКМД-библиотеки, разработаны собственные коллекции и аллокаторы. Разумеется, нужно упомянуть и о гигантском (и в основном незаконченном) проекте ECS. Техническое руководство Unity стратегически придерживается этой линии развития с 2018 года. Определённо, команда Unity считает, что для значительной части пользовательской аудитории быстродействие сценариев — ключевой фактор. Поэтому, переключаясь на Godot, я не просто перечёркиваю то, что было сделано в Unity за последние 5 лет — нет, всё гораздо хуже.
Именно об этом я недавно начал противоречивую, но продуктивную дискуссию в подреддите, посвящённом Godot. В этой статье я более детально изложу мысли, сформулированные в рамках этой дискуссии, тем более, что теперь я немного лучше понимаю, как работает Godot. Давайте это чётко отметим: в Godot я по-прежнему новичок, и в этой статье обязательно найдутся ошибки и заблуждения.
Замечание: далее высказываются критические замечания относительно того, как спроектирован и сработан движок Godot. Порой я эмоционально высказываюсь о том, что думаю и чувствую, но признаю, что разработчики Godot вытянули массу сложнейшей работы и создали повсеместно любимый продукт. Поэтому я совершенно не намеревался никого оскорбить или грубо переходить на личности.
Подробно разберём, как реализуется бросание лучей на C#
Далее подробно разберём, как в Godot реализуется функция, эквивалентная Physics2D.Raycast из Unity, и что происходит под капотом при использовании этой функции. Чтобы немного конкретизировать изложение, давайте для начала реализуем тривиальную функцию в Unity.
Unity
// Простое бросание лучей в Unity bool GetRaycastDistanceAndNormal(Vector2 origin, Vector2 direction, out float distance, out Vector2 normal)
Давайте быстро рассмотрим, как она реализована. Для этого проследим выполняемые вызовы.
public static RaycastHit2D Raycast(Vector2 origin, Vector2 direction) => defaultPhysicsScene.Raycast(origin, direction, float.PositiveInfinity); public RaycastHit2D Raycast(Vector2 origin, Vector2 direction, float distance, [DefaultValue("Physics2D.DefaultRaycastLayers")] int layerMask = -5) < ContactFilter2D contactFilter = ContactFilter2D.CreateLegacyFilter(layerMask, float.NegativeInfinity, float.PositiveInfinity); return Raycast_Internal(this, origin, direction, distance, contactFilter); >[NativeMethod("Raycast_Binding")] [StaticAccessor("PhysicsQuery2D", StaticAccessorType.DoubleColon)] private static RaycastHit2D Raycast_Internal(PhysicsScene2D physicsScene, Vector2 origin, Vector2 direction, float distance, ContactFilter2D contactFilter) < Raycast_Internal_Injected(ref physicsScene, ref origin, ref direction, distance, ref contactFilter, out var ret); return ret; >[MethodImpl(MethodImplOptions.InternalCall)] private static extern void Raycast_Internal_Injected( ref PhysicsScene2D physicsScene, ref Vector2 origin, ref Vector2 direction, float distance, ref ContactFilter2D contactFilter, out RaycastHit2D ret);
Итак, здесь выполняется совсем немного работы. Фактически, здесь вызов отводится в неуправляемое ядро движка при помощи внешнего механизма. Я думаю, это оправданно, и уверен, что в Godot будет сделано что-то подобное. Считайте, что это предвидение.
Godot
// Эквивалентное бросание лучей в Godot bool GetRaycastDistanceAndNormal(Vector2 origin, Vector2 direction, out float distance, out Vector2 normal) < World2D world = GetWorld2D(); PhysicsDirectSpaceState2D spaceState = world.DirectSpaceState; PhysicsRayQueryParameters2D queryParams = PhysicsRayQueryParameters2D.Create(origin, origin + direction); Godot.Collections.Dictionary hitDictionary = spaceState.IntersectRay(queryParams); if (hitDictionary.Count != 0) < Variant hitPositionVariant = hitDictionary[(Variant)"position"]; Vector2 hitPosition = (Vector2)hitPositionVariant; Variant hitNormalVariant = hitDictionary[(Variant)"normal"]; Vector2 hitNormal = (Vector2)hitNormalVariant; distance = (hitPosition - origin).Length(); normal = hitNormal; return true; >distance = default; normal = default; return false; >
Первым делом отметим, что этот код получился длиннее. Это не основной предмет моей критики, отчасти потому, что я сам отформатировал этот код именно так, чтобы он получился пространным. Это было сделано, чтобы код было проще разбирать построчно. Итак, давайте разберём, что же именно здесь происходит.
Для начала вызовем GetWorld2D() . В Godot все физические запросы выполняются в контексте игрового мира, и эта функция принимает тот мир, в котором выполняется наш код. Хотя World2D относится к управляемым классам, эта функция не делает никаких безумных вещей, в частности, не выделяет память всякий раз, когда мы ее запускаем. Ни одна из этих функций не должна делать ничего странного, если задача её — просто обеспечить бросание лучей, правильно?
Если заглянуть в эти вызовы API, то сразу видно, что даже очевидно простейшие из них – как, например, этот — реализуются при помощи довольно затейливых механизмов, и каждая такая операция сказывается на производительности, пусть и немного. Давайте в качестве примера разберём GetWorld2D , в частности, проясним некоторые вызовы, выполняемые на C#. Примерно так и выглядят все вызовы, возвращающие управляемые типы. Чтобы было понятнее, что тут происходит, я добавил в код комментарии.
// Это функция, которую мы подробно разбираем public World2D GetWorld2D() < // MethodBind64 – это указатель на функцию, которую мы вызываем в C++. // MethodBind64 хранится в статической переменной, поэтому перед тем, как извлечь его, нужно выполнить поиск в памяти. return (World2D)NativeCalls.godot_icall_0_51(MethodBind64, GodotObject.GetPtr(this)); >// Мы вызываем эти функции, опосредующие вызовы API. internal unsafe static GodotObject godot_icall_0_51(IntPtr method, IntPtr ptr) < godot_ref godot_ref = default(godot_ref); // Механизм try/finally даром не даётся. Чтобы с ним работать, нужно ввести конечный автомат. // Кроме того, он может блокировать JIT-оптимизацию. try < // Этап валидации, пусть даже весь код здесь является внутренним, и ему следует доверять. if (ptr == IntPtr.Zero) throw new ArgumentNullException("ptr"); // Здесь мы вызываем другую функцию, которая, фактически, вызывает указатель // и при помощи этого указателя помещает результат в godot_ref. NativeFuncs.godotsharp_method_bind_ptrcall(method, ptr, null, &godot_ref); // Далее предусмотрены механизмы для перемещения объектов через границу C#/C++. return InteropUtils.UnmanagedGetManaged(godot_ref.Reference); >finally < godot_ref.Dispose(); >> // Функция, фактически вызывающая указатель функции. [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static partial void godotsharp_method_bind_ptrcall( global::System.IntPtr p_method_bind, global::System.IntPtr p_instance, void** p_args, void* p_ret) < // Но подождите! // Ведь _unmanagedCallbacks.godotsharp_method_bind_ptrcall – это акт обращения к ещё одной статической переменной, // чтобы извлечь ещё один указатель функции. _unmanagedCallbacks.godotsharp_method_bind_ptrcall(p_method_bind, p_instance, p_args, p_ret); >// Честно говоря, этот вопрос я не изучал достаточно подробно, поэтому не могу комментировать, что здесь происходит. // В общем виде идея проста – здесь мы принимаем указатель на неуправляемый GodotObject, // переносим его в .Net, уведомляем об этом сборщик мусора, чтобы данный объект можно было отслеживать и // приводим его к типу GodotObject // К счастью, по-видимому, никаких операций выделения памяти здесь не происходит public static GodotObject UnmanagedGetManaged(IntPtr unmanaged)
В сущности, это немалые издержки. У нас несколько уровней косвенности между нашим кодом и кодом на C++, которые мы создаём при преследовании указателя (pointer chasing). На каждом из этих этапов выполняется поиск в памяти, а сверх того приходится заниматься валидацией, try finally и интепретацией возвращённого указателя. Может показаться, что всё это — всего лишь мелкие несогласованности, но, если каждому направляемому в ядро вызову и каждой операции доступа к свойству/полю в объекте Godot приходится проделывать весь этот путь, то издержки начинают накапливаться.
Присмотревшись к следующей строке, где выполняется доступ к свойству world.DirectSpaceState , окажется, что многие из этих операций мы уже проделывали. При помощи всё той же машинерии объект PhysicsDirectSpaceState2D опять вытягивается с территории C++. Не волнуйтесь, деталями вас утомлять не стану!
А вот следующая строка первая в этом коде, которая реально меня озадачила.
PhysicsRayQueryParameters2D queryParams = PhysicsRayQueryParameters2D.Create(origin, origin + direction);
Что тут может быть интересного, это же просто небольшая структура, в которую упакованы параметры бросания лучей, верно? Нет. PhysicsRayQueryParameters2D — это управляемый класс, а с точки зрения сборщика мусора — это как раз источник мусора, под который постоянно выделяется память. Настоящее безумие — оставлять такую штуку на оживлённом пути, на котором особенно критично выдавать максимальную производительность. Но ведь можно быть уверенным, что память здесь выделяется всего один раз, верно? Давайте-ка посмотрим, что внутри.
// Резюме: // Возвращает новый, заранее сконфигурированный объект Godot.PhysicsRayQueryParameters2D. С его // помощью быстро создаются параметры запроса, для этого применяются самые обычные опции. // var query = PhysicsRayQueryParameters2D.create(global_position, global_position // + Vector2(0, 100)) // var collision = get_world_2d().direct_space_state.intersect_ray(query) public unsafe static PhysicsRayQueryParameters2D Create(Vector2 from, Vector2 to, uint collisionMask = uint.MaxValue, Array exclude = null) < // Да, тут задействуются всё те же механизмы, что рассмотрены выше. return (PhysicsRayQueryParameters2D)NativeCalls.godot_icall_4_731( MethodBind0, &from, &to, collisionMask, (godot_array)(exclude ?? new Array()).NativeValue ); >
Ох. А вы тоже заметили?
Этот Array — массив Godot.Collections.Array . Это ещё один тип управляемого класса. Посмотрите, что происходит, если мы передаём ему значение null .
(godot_array)(exclude ?? new Array()).NativeValue
Верно, даже если мы не передадим массив exclude , программа продолжает работу и всё равно выделяет для нас целый массив в куче C#. Так что мы можем сразу же преобразовать его в нативное значение, представляющее собой пустой массив.
Чтобы передать два простых значения Vector2 (16 байт) функции бросания лучей, нам требуется выделить из кучи две отдельные порции данных общим объёмом 632 байта!
Как будет показано ниже, эту проблему можно сгладить, кэшируя PhysicsRayQueryParameters2D . Но, как вы уже понимаете из документирующего комментария, которым я снабдил код, API явно ожидает (и рекомендует) создавать свежие экземпляры для каждого акта бросания лучей.
Перейдём к следующей строке. Куда уж безумнее, правда?
Godot.Collections.Dictionary hitDictionary = spaceState.IntersectRay(queryParams);
Действительно, в результате бросания лучей возвращается нетипизированный словарь. И, да, он является источником мусора, так как выделяет в управляемой куче ещё 96 байт. Хотел бы я сейчас видеть, как вы озадачены и растеряны. «О, так, может быть, он хотя бы возвращает null , если ни на что не наткнётся? Нет. Если он ничего не найдёт, то он выделит и вернёт пустой словарь.
Здесь давайте перейдём непосредственно к реализации на C++.
Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Ref &p_ray_query) < ERR_FAIL_COND_V(!p_ray_query.is_valid(), Dictionary()); RayResult result; bool res = intersect_ray(p_ray_query->get_parameters(), result); if (!res) < return Dictionary(); >Dictionary d; d["position"] = result.position; d["normal"] = result.normal; d["collider_id"] = result.collider_id; d["collider"] = result.collider; d["shape"] = result.shape; d["rid"] = result.rid; return d; > // Это структура с параметрами, которую принимает внутренняя функция intersect_ray. // Здесь ничего особо безумного (хотя, exclude, вероятно, можно было бы доработать). struct RayParameters < Vector2 from; Vector2 to; HashSetexclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; bool collide_with_areas = false; bool hit_from_inside = false; >; // А вот вывод. Совершенно нормальное возвращаемое значение для ситуации с бросанием лучей. struct RayResult < Vector2 position; Vector2 normal; RID rid; ObjectID collider_id; Object *collider = nullptr; int shape = 0; >;
Как видите, тут обёрнута очень хорошо сделанная функция бросания лучей, только работает она безбожно медленно. Эта функция intersect_ray является внутренней, но она должна быть в API!
Этот код C++ выделяет нетипизированный словарь в неуправляемой куче. Если мы пристальнее в него заглянем, то, как и следовало ожидать, найдём там хеш-таблицу. Для инициализации этого словаря выполняется шесть операций поиска (при некоторых из них даже могут выполняться дополнительные выделения, но настолько подробно я в теме не разбирался). Но, подождите-ка, это ведь нетипизированный словарь. Как это работает? Используемая здесь внутренняя хеш-таблица отображает Variant на Variant.
Уф. Что еще за Variant ? Действительно, данная реализация довольно сложная, но, упрощённо говоря, это большое размеченное объединение (один экземпляр), куда включены все возможные типы, которые могут содержаться в этом словаре. Можно сказать, что перед нами динамический нетипизированный тип. В данном случае нас интересует, каков его размер — оказывается, 20 байт.
Так, хорошо, значит, каждое из этих «полей», которое мы записываем в словарь, имеет размер 20 байт. Ключи тоже такие. Помните те значения Vector2 по 8 байт? Теперь они по 20 байт. А те int? Тоже по 20 байт. Идею вы уловили.
Просуммировав размеры всех полей в RayResult , мы получим 44 байта (если предположить, что размер каждого указателя равен 8 байт). Если просуммировать размеры всех ключей Variant и значений, содержащихся в словаре, то получится 2 * 6 * 20 = 240 байт! Но, подождите-ка, ведь это хеш-таблица. В хеш-таблицах данные хранятся не компактно, поэтому реальный размер, занимаемый этим словарём в куче, будет, как минимум, вшестеро превышать размер тех данных, которые мы хотим вернуть, а, возможно, и гораздо сильнее.
Ладно, давайте вернёмся к C# и посмотрим, что происходит, когда мы возвращаем эту штуку.
// Функция, которую мы вызываем public Dictionary IntersectRay(PhysicsRayQueryParameters2D parameters) < return NativeCalls.godot_icall_1_729(MethodBind1, GodotObject.GetPtr(this), GodotObject.GetPtr(parameters)); >internal unsafe static Dictionary godot_icall_1_729(IntPtr method, IntPtr ptr, IntPtr arg1) < godot_dictionary nativeValueToOwn = default(godot_dictionary); if (ptr == IntPtr.Zero) throw new ArgumentNullException("ptr"); void** intPtr = stackalloc void*[1]; *intPtr = &arg1; void** p_args = intPtr; NativeFuncs.godotsharp_method_bind_ptrcall(method, ptr, p_args, &nativeValueToOwn); return Dictionary.CreateTakingOwnershipOfDisposableValue(nativeValueToOwn); >internal static Dictionary CreateTakingOwnershipOfDisposableValue(godot_dictionary nativeValueToOwn) < return new Dictionary(nativeValueToOwn); >private Dictionary(godot_dictionary nativeValueToOwn)
В первую очередь тут нужно отметить следующие вещи. Во-первых, мы создаём на C# новый управляемый словарь (да-да, и он тоже оставляет мусор при работе), а в этом словаре содержится указатель на тот словарь, что был создан в куче C++. Эх, хотя бы нам не приходится копировать содержимое этого словаря! На данном этапе пытаемся экономить на всём, где только можем.
Окей, так что же дальше?
if (hitDictionary.Count != 0) < // Приведение от строки к Variant может быть неявным – здесь я делаю его явным, чтобы было понятнее Variant hitPositionVariant = hitDictionary[(Variant)"position"]; Vector2 hitPosition = (Vector2)hitPositionVariant; Variant hitNormalVariant = hitDictionary[(Variant)"normal"]; Vector2 hitNormal = (Vector2)hitNormalVariant; distance = (hitPosition - origin).Length(); normal = hitNormal; return true; >
Надеюсь, к данному моменту уже хорошо прослеживается всё, что здесь происходит.
Если наш луч не встретит ни одной преграды, то будет возвращён пустой словарь. Поэтому мы проверяем значение, записанное в этом словаре, и так узнаём, сколько было попаданий.
Если мы попадаем в какую-либо преграду, то с каждым полем, которое мы хотим прочитать, проделываем следующие операции:
- Приводим ключи string к структурам C# Variant (это же делает и вызов, направляемый в C++)
- Преследуем ещё некоторые указатели функций, которые требуется вызывать в C++ — теперь нам уже привычно, как именно это происходит.
- Выполняем поиск в хеш-таблице, чтобы получить тот Variant , в котором содержится наше значение (естественно, это делается путём преследования указателя функции)
- Копируем эти 20 байт обратно на территорию C# (да, даже хотя мы читаем значения Vector2, в которых всего по 8 байт)
- Извлекаем значение Vector2 из Variant (да, здесь также приходится преследовать указатели до самого it C++, чтобы выполнить это преобразование)
Итак, приходится проделать немало работы, чтобы вернуть 44-байтовую структуру и прочитать пару полей.
Можно ли тут что-то улучшить
Кэширование параметров запроса
Если вы припоминаете, как мы работали с PhysicsRayQueryParameters2D , именно там нам удавалось обойтись без некоторых операций выделения памяти, если мы кэшировали нужные данные. Давайте снова это проделаем.
readonly struct CachingRayCaster < private readonly PhysicsDirectSpaceState2D spaceState; private readonly PhysicsRayQueryParameters2D queryParams; public CachingRayCaster(PhysicsDirectSpaceState2D spaceState) < this.spaceState = spaceState; this.queryParams = PhysicsRayQueryParameters2D.Create(Vector2.Zero, Vector2.Zero); >public bool GetDistanceAndNormal(Vector2 origin, Vector2 direction, out float distance, out Vector2 normal) < this.queryParams.From = origin; this.queryParams.To = origin + direction; Godot.Collections.Dictionary hitDictionary = this.spaceState.IntersectRay(this.queryParams); if (hitDictionary.Count != 0) < Variant hitPositionVariant = hitDictionary[(Variant)"position"]; Vector2 hitPosition = (Vector2)hitPositionVariant; Variant hitNormalVariant = hitDictionary[(Variant)"normal"]; Vector2 hitNormal = (Vector2)hitNormalVariant; distance = (hitPosition - origin).Length(); normal = hitNormal; return true; >distance = default; normal = default; return false; > >
Считаем: после первого луча удаляется 2/3 выделений памяти C#/GC на луч и 632/738, если перевести это в байты. Ситуация всё равно не так хороша, но, тем не менее, это прогресс.
Что насчёт GDExtension?
Как вы, возможно, слышали, Godot также предоставляет API для C++ (или Rust, или другого нативного языка), позволяющий нам писать высокопроизводительный код. Нам это здесь как раз пригодится, правда? Правда?
Оказывается, GDExtension предоставляет точно такой же the API. Ага. Можно писать быстрый код на C++, но всё равно вы получаете API, возвращающий нетипизированный словарь с раздутыми значениями Variant. Ситуация немного лучше, так как здесь можно не беспокоиться о сборке мусора, но… сейчас опять будет повод взгрустнуть, готовьтесь.
Совершенно иной подход — с узлом RayCast2D
Подождите! Действительно, ведь можно поступить совершенно иначе.
bool GetRaycastDistanceAndNormalWithNode(RayCast2D raycastNode, Vector2 origin, Vector2 direction, out float distance, out Vector2 normal)
Здесь показана функция, принимающая ссылку на узел RayCast2D в данной сцене. Как понятно из названия, это узел сцены, осуществляющий бросание лучей. Он реализован на C++, поэтому не проходит через вышеупомянутый API и не несёт всех издержек, связанных со словарями. Это довольно неуклюжий способ реализовать бросание лучей, поскольку нам нужна ссылка на узел в сцене, которую мы можем как хотим менять. Чтобы выполнить запрос, нам потребуется переставить узел в сцене. Но сначала давайте заглянем внутрь.
Сначала нужно отметить, что, как и ожидается, каждое из свойств, к которым мы обращаемся, проделывает полноценное преследование указателя, заходя за ним на территорию C++.
public Vector2 Position < get =>GetPosition() set => SetPosition(value); > internal unsafe void SetPosition(Vector2 position) < NativeCalls.godot_icall_1_31(MethodBind0, GodotObject.GetPtr(this), &position); >internal unsafe static void godot_icall_1_31(IntPtr method, IntPtr ptr, Vector2* arg1)
Теперь давайте посмотрим, что именно делает ForceRaycastUpdate() . Уверен, что код C# вам теперь вполне понятен, так что давайте углубимся в C++.
void RayCast2D::force_raycast_update() < _update_raycast_state(); >void RayCast2D::_update_raycast_state() < Refw2d = get_world_2d(); ERR_FAIL_COND(w2d.is_null()); PhysicsDirectSpaceState2D *dss = PhysicsServer2D::get_singleton()->space_get_direct_state(w2d->get_space()); ERR_FAIL_NULL(dss); Transform2D gt = get_global_transform(); Vector2 to = target_position; if (to == Vector2()) < to = Vector2(0, 0.01); >PhysicsDirectSpaceState2D::RayResult rr; bool prev_collision_state = collided; PhysicsDirectSpaceState2D::RayParameters ray_params; ray_params.from = gt.get_origin(); ray_params.to = gt.xform(to); ray_params.exclude = exclude; ray_params.collision_mask = collision_mask; ray_params.collide_with_bodies = collide_with_bodies; ray_params.collide_with_areas = collide_with_areas; ray_params.hit_from_inside = hit_from_inside; if (dss->intersect_ray(ray_params, rr)) < collided = true; against = rr.collider_id; against_rid = rr.rid; collision_point = rr.position; collision_normal = rr.normal; against_shape = rr.shape; >else < collided = false; against = ObjectID(); against_rid = RID(); against_shape = 0; >if (prev_collision_state != collided) < queue_redraw(); >>
Кажется, что тут много чего творится, но это только на первый взгляд. Если внимательно рассмотреть этот код, то видно, что структурно он практически аналогичен нашей первой функции GetRaycastDistanceAndNormal на C#. Она получает игровой мир, состояние, собирает параметры, вызывает intersect_ray для выполнения фактической работы, а затем записывает результат в наши свойства.
Но взгляните! Никаких выделений кучи, нет Dictionary и нет Variant . Вот так уже лучше. Можно предположить, что этот код будет работать гораздо быстрее.
Померяем время
Окей, мы неоднократно намекнули, что все эти издержки доставляют массу проблем, и не составляет труда увидеть, что без них будет лучше, но давайте перейдём к конкретным числам — позанимаемся бенчмаркингом.
Как было показано выше, функция RayCast2D.ForceRaycastUpdate() очень близка к самому минималистичному вызову intersect_ray из движка, обслуживающего игровую физику, так что давайте возьмём эту функцию в качестве отправной точки. Не забывайте, что и в этом вызове есть издержки, связанные с преследованием указателей. На каждой контрольной точке мы прогоняем 10 000 итераций тестируемой функции, с предварительным прогревом и фильтрацией выбросов. Сборку мусора я на время тестирования отключил. Такой бенчмаркинг игр мне нравится проводить на сравнительно слабом железе, поэтому, если попытаетесь воспроизвести мои тесты, то ваши результаты получиться даже лучше. Но нас в данном случае интересуют относительные числа.
В качестве модели возьмём простую сцену, в которой для столкновений предусмотрен круг, и наш луч в этот круг всегда попадает. Мы хотим измерить издержки на связывание, а не производительность игрового движка как такового. Мы имеем дело с задержками отдельных лучей, они измеряются в наносекундах, и поэтому числа могут получаться нелепо маленькими. Чтобы лучше проиллюстрировать, насколько они важны, также указываю кадровую частоту и указываю, сколько раз функция может быть вызвана в пределах одного кадра при кадровой частоте 60 кадр/сек и 120 кадр/сек, если в программе не делается ничего сверх тривиального бросания лучей.
Метод
Время (μs)
Базовый множитель
Кадровая частота (60 кадр/сек)
Кадровая частота (120 кадр/сек)
Выделение GC (байт)
ForceRaycastUpdate (скорость движка не важна)
Можно ожидать, что в типичном движке/API, чтобы максимально быстро бросать лучи, нужно использовать функцию, предназначенную именно для того, что описано в документации как канонический вариант. Как видим, если так поступить, то издержки на связывание/API приводят к тому, что код работает в 50 раз медленнее, чем «сырой» движок игровой физики. Ой!
Работая с тем же самым API, но разумно (пусть и иногда неизящно) подходя к кэшированию, можно сократить вышеупомянутые издержки до шестнадцатикратных. Уже лучше, но всё равно страшно.
Если вы ставите перед собой цель поднять производительность так, чтобы это было видно на практике, то нужно полностью отойти от традиционного/канонического/разрекламированного API, а вместо этого напрямую манипулировать объектами сцены и заставить их, чтобы они делали нужные нам запросы за нас. Казалось бы, что в разумно устроенном мире перемещать объекты по сцене вручную и требовать, чтобы они бросали лучи за нас, было бы медленнее, чем использовать API игровой физики без примочек, но на практике получается в восемь раз быстрее.
Даже при подходе с применением узлов код работает вдвое медленнее, чем с чистым движком (на самом деле, это даже недооценка). Таким образом, половину рабочего времени эта функция тратит на установку двух свойств и считывание трёх свойств. Издержки на связывание достаточно велики, так что на пять обращений к свойствам уходит столько же времени, сколько на бросание лучей. Давайте уложим это в голове. Даже не будем задумываться о том, что в реальном приложении нам вполне может потребоваться задать и прочитать ещё больше свойств, например, чтобы наложить маску слоя и прочитать значение счётчика попаданий.
На самом деле, в нижней части диапазона эти числа очень скудные. В моих нынешних проектах требуется более 344 актов бросания лучей на кадр. Разумеется, одним бросанием лучей работа в кадре не ограничивается. Этот тест — тривиальная сцена с единственной фигурой для столкновений. Но, если речь заходит о бросании лучей для выполнения реальной работы в более сложной сцене, то числа могли бы быть ещё ниже! Если бросать лучи стандартным способом, так, как это описано в документации, то вся игра намертво застопорится.
Также нельзя забывать и о том мусоре, который образуется в результате актов выделения памяти, происходящих в C#. Когда я пишу игры, я обычно придерживаюсь политики «ноль мусора на каждый кадр».
Чисто для интереса я также проделал бенчмаркинг Unity. Там делается полноценное рабочее бросание лучей с установкой параметров и извлечением результатов, всё примерно за 0,52 μs. До учёта присутствующих в Godot издержек на связывание оказывается, что скорость работы у ядер Unity и Godot оказывается сопоставимой.
Может быть, я тенденциозен
Когда я разместил тот тред на reddit, нашлось немало людей, которые говорили, что API игровой физики донельзя плох, поэтому по нему нельзя судить обо всём движке целиком. Честно, я совершенно не пытался выбрать API похуже — просто так получается, что именно бросание лучей я первым делом попробовал выполнить, взявшись разбираться с Godot. Правда, может быть, я немного лукавлю, поэтому давайте это проверим.
Если бы я хотел специально выбрать метод похуже, то долго искать бы мне не пришлось. Прямо рядом с IntersectRay находятся IntersectPoint и IntersectShape , для которых свойственны всё те же проблемы, что и для IntersectRay, а также ещё одна безуминка: дело в том, что, имея множественные результаты, они возвращают выделенный в куче управляемый Godot.Collections.Array ! O, кстати, этот Array — на самом деле типизированная оболочка, в которую обёрнут Godot.Collections.Array . Поэтому каждая 8-байтная ссылка на словарь на самом деле хранится в виде 20-байтного Variant . Конечно же, я выбрал не самый плохой метод в API!
Если просканировать весь API Godot (при помощи рефлексии C#), то, оказывается, что здесь не так много сущностей, которые возвращали бы Dictionary . Получается эклектичный список, где есть, в частности, метод AnimationNode._GetChildNodes , свойство Bitmap.Data , свойство Curve2D._Data (и 3D), некоторые вещи в GLTFSkin , кое-какой материал из TextServer , некоторые элементы NavigationAgent2D , т.д. Ни в одном из этих мест не годится иметь медленные словари, выделяемые в куче, но? даже на фоне всех вышеперечисленных методов, API игровой физики особенно плох.
Правда, мой опыт подсказывает, что во всём движке мало найдётся таких API, которые использовались бы столь же активно, как и физический. Если посмотреть вызовы API движка в моём коде геймплея, то оказывается, что примерно 80% из них приходятся на физику и преобразования.
Также не будем забывать, что Dictionary — всего лишь часть проблемы. Если чуть шире посмотреть, какие сущности возвращают Godot.Collections.Array (напомню: они выделяются в куче, по содержимому как Variant ), то найдётся масса деталей из физики, работы с игровыми сетками, геометрией, навигацией, картами замощений, рендерингом и многим другим.
Возможно, физика — особенно неудачная (но принципиально важная) зона ответственности данного API, но в ней глубоко укоренились проблемы, связанные с типами, выделяемыми в куче, а также с преследованием указателей вообще.
Так почему же мы до сих пор в ожидании Godot?
Основной язык сценариев, на котором написан Godot, называется GDScript . Это интерпретируемый язык с динамической типизацией, где почти все непримитивные типы выделяются в куче — то есть в этом языке нет аналога структур. Это утверждение должно было разразиться симфонией сирен в той части вашей головы, где вы задумываетесь о безопасности. Сделаю паузу, пока этот звон немного утихнет.
Если рассмотреть, как написанное на C++ ядро Godot предоставляет свой API, то найдётся кое-что интересное.
void PhysicsDirectSpaceState3D::_bind_methods()
При помощи этого разделяемого механизма генерируются связки для всех трёх скриптовых интерфейсов: GDSCript, C# и GDExtensions. В ClassDB собирают указатели функций и метаданные по каждой из функций API, которые затем как по конвейеру передаются через различные системы генерации кода с целью генерации связок для каждого языка.
Таким образом, каждая функция API проектируется прежде всего для купирования ограничений GDScript. IntersectRay возвращает нетипизированный динамический словарь Dictionary, поскольку в GDScript не существует структур. В нашем коде на C# и даже коде на C++ для расширений GDExtensions за это приходится платить катастрофически высокую цену.
Такой способ обработки связок через указатели функций также сопряжён с существенными издержками: как мы уже видели, даже простые обращения к свойствам идут медленно. Напомню, что каждый вызов начинается с поиска в памяти (находится указатель на ту функцию, которую требуется вызвать). Затем выполняется ещё одна операция поиска, чтобы найти указатель на вторичную функцию (которая, собственно, и отвечает за вызов первой функции). На всём этом пути выполняется дополнительный валидационный код, ветвление и преобразования типов. В C# (и, очевидно, в C++) есть быстрый механизм для отправки вызовов в нативный код. Он называется P/Invoke, но в Godot этот механизм просто не используется.
Итак, в философии Godot заложена его медленная работа. Единственная практическая возможность взаимодействия с движком — через его слой связывания, но ядро движка спроектировано так, что просто не может работать быстро. Сколько ни оптимизируй реализацию Dictionary, ни ускоряй физический движок — не уйдёшь от того факта, что мы передаём туда‑сюда целый ворох значений, выделенных в куче, тогда как здесь следовало бы работать с крошечными структурами. Поскольку API C# и GDScript остаются синхронизированными, это неизменно тормозит развитие движка.
Окей, так давайте же это исправим!
Что можно сделать, не отступая от работы с имеющимся уровнем связывания?
Если предположить, что по-прежнему необходимо поддерживать совместимость GDScript со всеми нашими API, то всё равно остаётся несколько областей, в которых, пожалуй, можно что-то подправить, даже если получится и не очень красиво. Вернёмся к нашему примеру с IntsersectRay.
- GetWorld2D().DirectStateSpace можно ужать с двух вызовов до одного, введя в код GetWorld2DStateSpace() .
- Проблемы с PhysicsRayQueryParameters2D можно устранить, добавив такую перегрузку, при которой все поля принимаются как параметры. Всё это позволило бы нам примерно сравняться по производительности с CachedRayCaster (в 16 раз медленнее базовой), не прибегая к кэшированию.
- От выделения Dictionary можно избавиться, разрешив передавать для записи такой словарь, который находится в кэше/пуле. По сравнению со структурами такой подход уродливый и неуклюжий, зато без выделений.
- Процесс поиска в словаре до сих пор смехотворно медленный. Его можно было бы улучшить, возвращая класс с ожидаемыми свойствами. От операции выделения здесь можно было бы избавиться, применив кэш/пул так, как было описано в случае с Dictionary .
С точки зрения пользователя все эти варианты не слишком красивы и эргономичны, но, если наша цель — расставить дешёвые и сердитые патчи, просто чтобы работало, то как‑то работать будет. Так можно было бы исправить проблему с выделениями, но скорость выполнения будет, пожалуй, всего вчетверо больше базовой, так как сохраняется всё межъязыковое преследование указателей и приходится управлять кэшированными значениями.
Также можно было бы улучшить код, сгенерированный для всех операций с преследованием указателей. Я пока детально не изучал этот вопрос, но, если там найдутся потенциальные выигрыши, то они будут применимы и в рамках всего API, и это будет круто! Как минимум, можно было бы убрать из релизных сборок валидацию и блоки try finally.
Что если бы было разрешено добавлять дополнительные API для C# и GDExtensions, такие, которые несовместимы с GDScript ?
Отлично, давайте поговорим об этом! Если мы считаем, что это возможно (может быть, это уже реализовано, но я точно не знаю), то, теоретически, можно было бы добавить к имеющимся связкам ClassDB другие, более качественные, которые взаимодействовали бы напрямую со структурами через полноценные механизмы P/Invoke. Таков путь к приемлемой производительности.
К сожалению, если продублировать весь API такими улучшенными версиями, то код превратится в огромную мешанину. Это можно было бы преодолеть, например, размечая сущности [не рекомендуется] и подталкивая пользователя в верном направлении, но из-за таких проблем как конфликты имён всё станет совсем уродливо.
А что, если снести всё до основания и сделать заново?
Безусловно, в краткосрочной перспективе такой вариант очень болезненный. Godot 4.0 вышел совсем недавно, а тут я говорю об обратной совместимости, ломающей весь redux API, практически о Godot 5.0. Правда, если быть честным с самим собой, то это единственный жизнеспособный вариант, который позволил бы года за три привести движок в порядок. Если бы мы смешивали медленные и быстрые API, так, как это описано выше, это стало бы для нас головной болью на многие десятилетия. Подозреваю, движок угодит как раз в эту ловушку.
А не кликбейтный ли заголовок у этой статьи? Может, я кого-то на слезу пробить хочу?
Может быть, немного. Но не слишком.
Найдутся люди, которые пишут игры на Unity и могли бы делать точно такие игры на Godot, не будь перечисленные проблемы настолько острыми. Возможно, Godot отгрызёт у Unity эконом-сегмент её рынка. Но тот факт, что недавно в Unity стали тщательно улучшать производительность — хороший индикатор. Он означает, что на это есть спрос. Я знаю, что для меня это действительно. Но у Godot производительность не просто хуже, чем у Unity, она драматически и систематически хуже.
В некоторых проектах 95% нагрузки на ЦП даёт алгоритм, который даже не касается API движка. В таком случае, всё это не имеет значения (сборщик мусора важен всегда, но с ним проблемы можно решать при помощи GDExtensions). Во многих других случаях важно обеспечить качественную реализацию физики/столкновений в программе и вручную модифицировать свойства огромного количества объектов, что играют в проекте ключевые роли.
Многим просто важно знать, что такие вещи можно сделать, если потребуется. Может быть, вы два года занимались проектом, полагая, что в нём не потребуется ничего, кроме бросания лучей, но потом, на позднем этапе разработки игры, было решено реализовать какие-то элементы работы с ЦП, которые позволяли бы проверять столкновения. Это совсем небольшая красивость, но вдруг вам требуется обращаться к API движка — и у вас проблемы. Много слов сказано о том, как важно доверять движку и знать, что в будущем он сможет послужить вам опорой. В Unity есть проблема с мутными бизнес‑практиками, а в Godot — с производительностью.
Если Godot стремится повоевать с Unity на её основном рынке (кстати, я не знаю, стремится ли в самом деле), то в Godot требуются быстрые и фундаментальные изменения. Многие из вещей, рассмотренных в этой статье, для Unity-разработчиков просто неприемлемы.
Обсуждение
Я опубликовал эту статью в подреддите r/Godot, и там развернулась весьма активная дискуссия. Если вы пришли в этот пост с какого-то другого сайта, то не стесняйтесь высказываться и комментировать.
Благодарю
- _Марио Босса с reddit за то, что он первым обратил моё внимание на фокус с узлами при работе с Raycast2D.
- Джона Риччительо за то, что наконец‑то мотивировал меня подробнее исследовать другие движки.
- Майка Бизелла за то, что позволил позаимствовать его шутку с предвидением. На самом деле, разрешения я не спрашивал, но он, по‑видимому, настолько добрый малый, что не стал искать меня и разбираться.
- Фрейю Хольмер, так как при работе над этой статьёй было крайне забавно читать её жалобы о том, что в Unreal физика делается на уровне сантиметров. Жду, когда она перепугается, как и я, когда обнаружит, что в Godot есть такие единицы, как килограммы на пиксель квадратный. Кстати, одну из моих шуток всё‑таки заметили.
- Клэнки с reddit за подсказку, что у меня случайно затесались наносекунды там, где должны быть микросекунды.
Godot Engine
Godot Engine — открытый кроссплатформенный игровой движок для разработки 2D/3D-видеоигр и приложений для ПК, мобильных устройств, веб-платформ. Адаптирован ко всем распространенным операционным системам, включая Linux, macOS, Windows, Android и iOS.

Освойте профессию «Разработчик игр на Unity»
Godot разработали в 2007 году два программиста из Аргентины — Хуан Линецкий и Ариэл Манзур. Первоначально его использовали несколько игровых студий Латинской Америки. В 2014 году разработчики выложили движок на GitHub по лицензии MIT. В декабре того же года вышла первая стабильная версия 1.0. С этого момента началось развитие проекта и его распространение в других странах.
Возможности Godot
Встроенный функционал «Годо» позволяет разработчику с нуля создать полноценную игру или приложение без использования внешних инструментов.
- Работа с двух- и трехмерной графикой — поддержка эффектов отражения, динамических теней, статичного и динамичного глобального освещения, полноэкранной постобработки (засветки, глубины резкости, гамма-коррекции и т.д.).
- Поддержка реалистичной физики — системы частиц (дыма, тумана, пара, взрывов и т.д.), свойств динамичных и статичных тел, столкновений и разрушений, трассировки лучей и других физических процессов.
- Работа с анимацией — опции создания скелетной анимации, наложения объектов, кат-сцен в реальном времени.
- Сетка навигации (Navigation mesh) — алгоритм нахождения игровым агентом оптимального маршрута в сложном пространстве.
- Поддержка мультимедиа — воспроизведение аудио- и видеофайлов с помощью подключаемых кодеков Theora, OGG Vorbis, WAV.
- AR/VR — встроенный мобильный интерфейс дополненной и виртуальной реальности с использованием 3DOF-датчиков на телефоне.
- Подключение устройств ввода — клавиатуры, мыши, геймпада и сенсорного экрана.
- Процедурная генерация — автоматическое создание внутриигрового контента (окружения, NPC, объектов, оружия и т.д.) с помощью алгоритмов.
- Поддержка языков — «Годо» имеет свой собственный высокоуровневый язык программирования GDScript, также можно использовать С# и C++.
Профессия / 18 месяцев
Разработчик игр на Unity
Создавайте виртуальные миры

Возможности Godot можно расширить с помощью плагинов и сторонних приложений. Например, движок позволяет импортировать сцены из Blender с настроенным освещением, камерами, физикой столкновений, анимированными персонажами и т.д. Также есть возможность подключать разработанные самостоятельно или сторонние плагины виртуальной/дополненной реальности, кодеки для воспроизведения видео и аудио, визуальные редакторы.
Ключевые концепции Godot
Работа движка Godot основана на представлении игры как дерева узлов, которые группируются в сцены и взаимодействуют друг с другом с помощью сигналов и других способов.
Узлы. Минимальные функциональные единицы игровой архитектуры, «кирпичики», из которых собирается вся игра. Каждый узел может выполнять несколько специализированных функций и имеет следующие атрибуты:
- уникальное наименование;
- изменяемые свойства;
- способность расширяться и получать новые функции;
- обратную связь для обработки кадров;
- способность присоединяться к другим узлам в качестве дочернего.
Узлы различаются по своему назначению. Одни показывают изображение, другие отображают 3D-модели, третьи воспроизводят звук. Подключая один узел к другому, можно получать дерево узлов, обладающее более сложным функционалом. На этом строится основной принцип разработки игры.
Сцены. Это дерево иерархически соединенных друг с другом узлов. Имеет следующие атрибуты:
- один корневой узел, к которому, подобно ветвям, подсоединяются дочерние;
- возможность сохранения на диск и загрузки обратно в редактор;
- возможность создания экземпляров (реплик);
- возможность подгружать одни сцены в другие в runtime.
Сценами могут быть персонажи, оружие, локации, целые уровни и другие объекты игрового мира, пользовательский интерфейс в приложениях и т.д. Они обладают двумя важными свойствами:
- выступают в качестве префабов — «заготовок», задающих изначальную структуру и свойства для экземпляров;
- вкладываются друг в друга — например, персонажа можно разместить на уровне, а в руки ему дать оружие или магический посох.
Дерево сцен. Это совокупность иерархически связанных сцен. Создаваемый в Godot проект (игры, приложение) — последовательность их выполнения. А сам движок — редактор, в котором разработчик продукта определяет порядок и способ исполнения взаимосвязанных сцен. При запуске проекта сначала инициируется основная (корневая) сцена, которая последовательно запускает остальные.

Разработчик игр на Unity – одна
из самых творческих профессий в IT. Создайте виртуальные миры уже через полгода обучения
Сигналы. Это сообщения, отправляемые узлами, когда с ними совершается какое-либо действие. Например, когда пользователь кликает на кнопку, она испускает сигнал. Подключенные узлы реагируют на него и вызывают ответную функцию. При этом узлы, взаимодействующие с помощью сигналов, не ссылаются друг на друга. Это ограничивает их связанность и делает код более гибким.
Вместо программирования по строгим шаблонам Godot предлагает разработчику более гибкий, интуитивно понятный метод создания игр и приложений. Но для использования потенциала движка потребуется знать основы объектно-ориентированного программирования.
Преимущества Godot
Простота. Godot — сравнительно простой в освоении и использовании игровой движок. Работать с ним могут как опытные разработчики, так и начинающие энтузиасты. Встроенный язык программирования GDScript имеет почти такой же синтаксис, что и Python, и прост для изучения. Интуитивно понятный редактор, возможность интеграции со сторонними плагинами и приложениями также снижают порог вхождения.
Дополнительные функции, шаблоны, плагины и прочий контент можно скачивать по мере необходимости, не перегружая компьютер. Особенность «Годо» — одинаковый уровень производительности движка и созданных с его помощью игр.
Поддержка сторонних языков. В ядро Godot уже встроена возможность работы на GDScript, C# и C++. Также модуль GDNative позволяет привязать к ядру движка код, написанный на других языках программирования. С помощью системы VisualScript программировать можно без кода, работая на уровне узлов. Это подходящий вариант для новичков не только в геймдеве, но и в программировании в целом.
Гибкость. Система деревьев узлов и сцен позволяет разрабатывать игры на интуитивно понятном уровне. Хотя тем, кто работал с другими игровыми движками, подход кажется непривычным.
Независимое 2D и 3D. Godot создавался как двухмерный игровой движок, 3D-редактирование появилось позже. Разработчики оставили для каждого режима свой редактор, а не стали использовать псевдодвухмерный. Возможность работы с пиксельным 2D упрощает разработку и оптимизацию двухмерных игр. Это ценят разработчики небольших инди-проектов.
Открытый исходный код. Godot — бесплатное программное обеспечение, распространяемое по лицензии MIT. Созданные игры и приложения являются собственностью разработчика. Кроме того, открытость движка способствует появлению множества расширений и инструментов. При отсутствии функции в ядре «Годо» ее можно получить, скачав подходящее дополнение с официального сайта или ресурсов, входящих в экосистему.
Кроссплатформенность. Godot существует в версиях для Windows, Mac, Linux, Android, iOS. Также есть поддержка универсальной платформы UWP от Microsoft, на которой можно разрабатывать приложения для Windows 10, Windows Mobile, Xbox One и виртуальной среды HoloLens без необходимости переписывать код под каждую ОС.
Обширная документация. По «Годо» есть множество информационных материалов (мануалов, справочников, статей и т.д.) от официальных разработчиков, сторонних профессионалов и энтузиастов-любителей. На любой вопрос по работе с движком можно найти ответ в сообществе.
Недостатки Godot
Недостаточная проработка 3D. По этому параметру Godot уступает конкурентам вроде Unity или Unreal Engine. «Годо» развивался как 2D-движок, трехмерный редактор был добавлен позже. В последних версиях работа с 3D значительно улучшена.
Сложности с разработкой консольных приложений. Разработчики отмечают проблемы при создании или портировании «Годо»-игр на консоли. Это требует использования сторонних инструментов и большого опыта. Одна из возможных причин проблемы — закрытый характер консольных инструментов, что противоречит открытости самого движка.
Использование Godot
Открытый исходный код, простота и особенности редактора «Годо» сделали движок популярным в среде разработчиков инди-игр. Из известных гейм-девелоперов, использовавших его в своих проектах, — аргентинская компания OCAM Studio и LRDGames, Inc., выпустившая в 2021 году сатирическую стратегию Rogue State Revolution. Также этот движок применяется в разработке:
- мобильных игр, в том числе многопользовательских (платформеров, пазлов, головоломок);
- приложений — мультиплееров, планировщиков, музыкальных редакторов и т.д.
Godot популярен в качестве учебного пособия для обучения азам компьютерной графики, программирования и геймдева. Он часто используется в специализированных и общеобразовательных учебных заведениях.
В сегменте игр категории АА и ААА игровой движок Godot Engine пока не получил распространения. Но в последних версиях начал развиваться 3D-редактор, появились функции и встроенные инструменты для работы с трехмерной высокополигональной графикой.
Разработчик игр на Unity
Все главные навыки разработчика игр на одном курсе. Вы освоите все этапы геймдизайна, научитесь программировать на С# и создадите 7 игр во время курса.
Godot Engine. Обзор игрового движка


Этот материал актуален для молодых игроделов –кто делает первые шаги в индустрии и мучительно выбирает движок. А также для тех разработчиков, кто устал вносить денежки владельцам проприетарного ПО и хотел бы пересесть на что-то подешевле.
Статья написана с целью познакомить сообщество с игровым движком Godot, а не сравнить его возможности с конкурентами, поэтому попрошу воздержаться от холивара на тему «чьи поезда поездатее».
Мною было приложено много усилий, чтобы обзор получился ёмким и более-менее объективным. Это не копипаста чьей-то более ранней статьи, обзор основан на личном опыте использования движка.
Немного истории
Разработкой движка Godot (читается «годо») с 2007 года занимались Хуан Линетски и Ариель Манзур. Стоит отметить, что в те бородатые времена движок был проприетарным, закрытым и создавался для нужд частных заказчиков.

В 2014 году авторы выпустили обновлённую версию движка под лицензий MIT и выложили исходники на GitHub, разработка перешла сообществу Godot Engine Community, и продолжается до сих пор.
Godot Engine – очень компактный (~74MB), быстрый и оптимизированный движок, позволяющий создавать с нуля любую игру любого жанра. Он кроссплатформенный, мультифункциональный, бесплатный, опенсорсный.
Кстати «с нуля» здесь ключевое. В базовой сборке Godot не имеет шаблонов для игровых процессов, однако есть огромное количество плагинов, аддонов и внешних библиотек, которые могут помочь со стартом. Доступ к репозиторию осуществляется прямо из окна запуска движка. Просто переходим на нужную вкладку и листаем 😉

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

Несмотря на свою легковесность, Godot обладает необходимым и достаточным функционалом разработки (об этом ниже), а так же берёт на себя базовые оптимизационные задачи, такие как: управление памятью и ресурсами компьютера, интеграция устройств ввода, сборка и оптимизация продукта под различные платформы – от мобильных, до консолей.
При этом базовая сборка не тащит за собой «ваще все библиотеки, которые только есть в природе» – вплоть до того, что в ней отсутствуют инструменты для билда. Godot – это конструктор. Он не знает, чем вы будете заниматься, поэтому предоставляет функционал разработки… и… всё! Остальное вы докачиваете сами по мере необходимости.
Периодически в этих ваших интернетах на форумах и у обзорщиков проскальзывает снисходительная ремарка «Godot – движок для первой игры, и всё». Это не так. Godot – высокоуровненвый профессиональный инструмент, достаточно дружелюбный, но своеборазный и сложный в освоении, если вы хотите нарисовать что-то сложнее пиу-пиу платформера.
Среда разработки
Godot «из коробки» обладает всеми необходимыми компонентами для разработки, отладки, тестирования и конструирования игры, не требует использования дополнительного ПО для создания программной и архитектурной составляющих (разумеется, вам в любом случае потребуются программы для создания визуального контента, звуковых ассетов, etc.).
Однако, если по какой-то причине, встроенные инструменты вас не устраивают, вы легко можете воспользоваться привычным. Godot умеет дружить со множеством внешних редакторов и IDE.
Для воплощения ваших самых смелых идей он имеет 2D и 3D пространство со стандартным набором классов и объектов, а так же редактор скриптов и два редактора шейдеров — для прямого программирования и визуальной настройки. Поведение любого класса вы можете расширять и/или изменять по мере надобности.
Об особенностях рендера и визуальной среды ниже.
Редактор скриптов обладает возможностями дополнения кода, авто-отступами, подсветкой синтаксиса, быстрым доступом к API движка и докам.
Интерфейс приятный, лакончиный и довольно интуитивный:

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

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

Возможно, вам трудно осознать преимущества этого подхода, поэтому отмечу, что упрощённая система хранения данных обеспечивает лёгкий доступ всех членов команды разработчиков ко всем ассетам (мы не зависим от версии БД, текущей версии продукта и даже версии самого движка!), а так же сильно облегчается контроль версий — особенно если применяете внешние системы управления.
Godot исользует собственный высокоуровневый динамически типизированный скриптовый язык программирования — GDScript, который является плодом порочной связи гибридом Python и Lua.
Язык специализировался и оптимизировался под ранее упомянутую архитектуру систем сцен и узлов, однако если по какой-то причине вам хочется писать на другом языке (допустим, не хватает каких-либо инструментов, или вы просто не хотите осваивать новый синтаксис), Godot умеет интегрировать другие языки программирования, в частности C#, C++, Rust.
Помимо этого (начиная с версии 3.0) присутствует компонент для визуального программирования — Visual Scripting. Про него не могу ничего сказать, не приходилось пользоваться, но, думаю, это легко нагуглить.
Идеология движка имеет строгое ограничение: один узел — один скрипт. Однако, если вам необходимо менять поведение и/или состояние объекта в зависимости от игрвого состояния, Godot любезно предоставляет возможность заменять один скрипт на другой «на лету» или пользоваться внешними скриптами, которые вообще не привязаны ни к одному узлу — например, это могут быть списки оружия, брони и соответствующее им поведение, которое подхватывается из мирно дремлющего скрипта активным и применяется.
Визуализация
Графическая система — OpenGL ES. Для рендеринга 3D-сцен применяются технологии order-independent transparency, normal mapping, specularity, полноэкранные постэффекты типа FXAA, bloom, DOF, HDR, гамма-коррекции, distance fog, динамические тени на основе shadow maps и другие.
Отдельно стоит отметить превосходную симуляцию освещения и постобработки. В возможностях манипуляций со светильниками Godot не уступает движкам, специализирующимся на кинематографических эффектах для игр.
В отличие от многих других движков, которые имитируют 2D-среду на 3D пространцстве, 2D компонент Godot полностью изолирован, оптимизирован и имеет свой собственный набор классов и объектов. Следствием этого является компактность и быстродействие готового игрового продукта (мы не тащим с собой тяжёлые 3D-объекты и обвязку к ним там, где это не требуется), а так же удивительная лёгкость манипуляций с 2D компонентами в процессе разработки.

Помните, выше упоминалось, что Godot поддержит вас в любых самых сумасшедших начинаниях? 😉 Стартуя работу с 2D сценой, вы легко можете добавить в неё 3D объекты или целые блоки, воспользовавшись многоуровневой системой вьюпортов. Благодаря изоляции 2D и 3D пространства (и, разумеется, многопоточности) компоненты не мешают друг другу и не тормозят работу продукта. В обратную сторону это тоже работает 😉
Игровая физика
Физический движок для 2D и 3D тоже уникальный и разработан с нуля, что позволило добиться требуемого уровня оптимизации физической подсистемы. Реализованы возможности рейкастинга, обнаружение столкновений, динамики твёрдых тел и соединений между ними. Так же имеется обширный арсенал инструментов, осуществляющих кинематику.
Кстати, объекты предназначенные для распознавания физических взаимодействий, полностью изолированы от визуализационных, что облегчает манипуляции с теми и другими и гарантирует, что вы не поломаете визуал своего сложного десептикона столкновением с автоботом.
К сожалению, в версиях движка 3.0 — 3.5 (к настоящему моменту самая свежая из стабильных) на 2D пространстве отсутствует физика частиц — поведение имитируется, оставаясь не более, чем визуальным эффектом. Честной физики мы тут не увидим. В Godot 4.0 этот компонент улучшен, но это всё ещё альфа — имейте это в виду, если захотите поиграть с физикой частиц в новой версии движка. Для 3D всё в порядке.
Напоминаю, для того, чтобы сбилдить проект вам сперва нужно скачать и настроить соответствующий компонент. Выбор при этом у вас впечатляющий. Godot поддерживает Windows (и UWP OS), MacOS, X11 (Linux, BSD), Android OS, iOS, HTML5. Также можно производить экспорт на другие платформы вручную через компилирование движка для SDK целевой платформы.
Система ввода поддерживает клавиатуру, мышку, геймпад и сенсорный экран (разные устройства могут быть назначены на абстрактное действие, и оно будет рассматриваться независимо от использованного метода ввода).
Подведём итоги
Здесь перечислены плюсы и минусы движка в голом виде — без дополнительных библиотек и плагинов, как будто вы его только что скачали.
— не трубет установки;
— эффективное управление ресурсами компьютера;
— удобство для использования;
— быстрый доступ к справке и внешним библиотекам;
— возможность взаимодействия с компонентами управления из вашего скрипта (например, можно статистику смотреть не на выделенной панели, а вывести прямо во вьюпорт игры).
— скундый набор инструментов визуальной разработки;
— отсутсвие предустановленных тимплейтов;
— отсутствие встроенных инструментов для билда;
— неудобные инструменты вёрстки диалоговых окон;
— слабые AR/VR компоненты;
— осутствие физики для 2D частиц;
— отсутствие возможности редактирования мешей и уровней сглаживания;
— низкая популярность в России (очень мало материалов на русском языке).
Благодарю за внимание! Надеюсь, вам было интересно в общих чертах познакомиться с Godot. Если у вас остались вопрсы, можете задать их в комментах, постараюсь ответить на все 🙂
Всем хорошего дня, вдохновения и успехов в освоении Godot!
P.S.: Следующим постом выложу полезные материалы для новичков с кратким описанием полезности.
P.P.S.: К сожалению, невозможно запихать в один обзор всю полезную и интересную информацию, поэтому в перспективе планирую сделать подробное описание каждого блока с разбором функциональных компонентов. Пожалуйста, посигнальте в комментах, если эта информация вам интересна.
Поддержать

77 постов 240 подписчиков
Подписаться Добавить пост
Правила сообщества
Нельзя писать плохой про Godot и можно писать хороший про Godot. Borat.jpg
Упоминание других движков допустимо только в технических сравнениях иначе — вы юнитист и бог вам судья.
1 год назад
@46165957 оргомное спасибо за волшебный пендель! ^_^ От осознания того, что это может быть Вам интересно, мотивации ощутимо прибавилось 🙂
раскрыть ветку
1 год назад
Помимо этого (начиная с версии 3.0) присутствует компонент для визуального программирования — Visual Scripting. Про него не могу ничего сказать, не приходилось пользоваться, но, думаю, это легко нагуглить.
не так давно объявили, что его скоро не будет
раскрыть ветку
1 год назад
Подписался, будем ждать!
раскрыть ветку
1 год назад
С годо всё отлично. Вполне работоспособный, гибкий инструмент (верстак!) для разработки игрушек, или других десктопных приложений. В принципе, он вроде как «сам на себе» написан 🙂
Меня в нём удручает некоторая бедность библиотек и лёгкая «корявость», например, встроенного дебаггера.
Впрочем, я вполне допускаю, что это от «привычки к шибко хорошему» вроде Visual Studio (с его сверхмощными средствами отладки) и всякими linq, позволяющими проворачивать функциональную магию со всякими перечислениями.
С другой стороны, вполне вероятно, что у годо оно всё тоже есть, но в виде отдельных дополнительных пакетов, библиотек и расширений среды.
1 год назад
Хочу попытаться в годот, боюсь что не смогу потянуть, тяжело дается кодинг.
Опыта 0, а то что я 6 лет в консольном левел билдере работал это вряд ли поможет. Но очень хочется попробовать на самом деле, надеюсь смогу.
раскрыть ветку
Похожие посты
22 часа назад

Как я игровую импотенцию лечу
Для ЛЛ: пишу собственную космическую онлайн стратегию.
Чуть больше тезисно для ЛЛ:
Строим домики:


Колонизируем новые планеты

Застроенная новая планета

Отправка флотилий, пример отправки флота для колонизации
И делаем ПИУ-ПИУ по другим игрокам!
Сейчас это представлено в довольно кривом текстовом формате в сообщениях пользователя так как дальше я буду делать полноценную ртс, где игроки смогут управлять довольно большими флотилиями из кораблей собранных по своему желанию и стремлению в игре 🙂
Ну, а теперь немного развернуто о том как я пришел к тому, что начал писать свою игру.
По сути я являюсь большим фанатом космических стратегий и всевозможных жанровых ответвлений, Стелларис, XGame/OGame-ы, Закат солнечной империи, Гегемония, Star Wars Empire at war, Sword of the Stars I и II, так же частично можно сюда отнести и Supreme Commandor, Косморейнджеры, ну куда же без них, хотя по сути последние не то чтобы сильно стратегия, да и пофиг 🙂 так же я обмазывался всевозможными аддонами и модами для всех этих игр, казалось бы

и все же в каждой мною любимой игре всегда были какие то недостатки, точнее даже не так, там не хватало вещей которые мне так хотелось видеть в каждой из этих игр, не поймите неправильно, я обожаю все эти игры и время от времени провожу в них много часов играя и получая удовольствие, а о плюсах каждой могу говорить часами и все же. вас никогда не преследовало чувство, что вот сидишь ты играешь, кайфуешь, но круто было бы, если в этой игре было еще и ? И у меня такое чувство постоянно и к сожалению моды вообще в некоторых случаях не спасают 🙁 вот так и родилась идея того, чтобы создать собственную стратегию с блекдж. кхм, ну вы поняли. Идея была такова, что я хочу вобрать самое лучшее из тех игр и соединить это в единый проект хоть и в простом относительно 2Д формате, возможно в 3Д когда-нибудь перееду, как наберусь опыта в игрострое, ибо у меня его ноль целых нифига десятых, тем более заготовки я под это делал 🙂
Итак, что же можно на данный момент в моей стратегии?
По сути после регистрации у вас появляется планета как на первой картинке, только пустая, планета собой представляет клетки ( привет плиточкам из стеллариса), на которых могут быть какие то ресурсы, а могут и не быть 🙂

нажав на плитку, вы можете там построить любое здание,

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

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

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

Показать полностью 10
12 дней назад

Удержание игроков с помощью метрик

На примере моей игры «Эпик Шутер» расскажу насколько может быть полезно интегрировать метрику в вашу игру для площадки Яндекс Игры.
Игра на движке Unity. Интеграция SDK Яндекс Игр с помощью плагина PluginYG.
Я сделал эпичный шутер под ритмичную музыку, вы можете попробовать поиграть в него для понимания описанного в этой статье анализа. Анализ состоит в том, чтобы понять на каких моментах игроки покидают игру и исправить недочёты. Это можно узнать благодаря сервису Яндекс Метрика.
Я не пытаюсь рекламировать свою игру здесь, поиграть в неё предлагаю лишь для понимания описанного. Знаете, Яндекс Игры льют трафика гораздо больше, чем вы сможете привлечь рекламируя свою игру сами. Но об этом поговорим в другой раз, а сейчас о том — как может помочь интеграция метрик в вашу игру.
В начале я расскажу что было после релиза игры, какие вскрылись недостатки, моменты на которых люди выключают игру. Поделюсь и другими причинами непопулярности игры (всё относительно конечно).
Затем расскажу что стало после исправления недочётов, которые мне показала метрика, и как преобразились результаты после обновления игры. Забегая вперёд — мне удалось удержать более 50% игроков!
Релиз игры
Наверное, всем интересно услышать сколько можно заработать на своей игре. Делюсь результатом, сколько принесла игра за две недели после релиза:
3450 рублей. Были по какой-то причине пики и до 1000р в день, но в итоге игра остановилась на доходе 50р в день.
Интересно то, что практически половина игроков иностранцы. Должно еще с них что-то прийти (пока нет информации по доходу с иностранцев).
Вернёмся к метрикам.
Я повесил метрики на загрузку уровней, финиш, и на ключевые триггеры в тренировочном уровне. И вот что получилось:
22% выходят из игры сразу после включения первого уровня. Может быть игра тормозила, а может игроков не устроил нож в руке на первых секундах вместо огнестрела. Отсутствие противников или всплывающая подсказка могла стать причиной для выхода из игры.
Но послушайте по какой причине отвалились следующие 50% игроков! На моменте где нужно перепрыгнуть между домами 50% игроков выходят вероятно только потому, что при прыжке у персонажа в воздухе нет инерции и ощущения не привычные. Значит даже такая мелочь может отпугнуть 50% игроков Яндекс Игр.
Далее 13% не доходят до оружия автомата.
Потом еще 30% покидают игру при входе в дом, видимо, из-за всплывающей подсказки. Наверное, тут игрокам уже нужен экшон, а не табличка с текстом.
Зато 2-й и 3-ий уровни проходили больше, чем первый тренировочный. Значит часть игроков проходили игру на второй раз или первые уровни.
Основные вероятные причины почему игра не стала популярной:
Тематика игры. Без трендовой темы в Яндекс Играх очень сложно выстрелить.
Обложка/иконка. CTR обложки низкий. Думаю, детям нужны более яркие краски и, опять же, популярные персонажи на картинке.
Оптимизация. Она как я считаю у игры отличная. Но загруженность локации для веба слишком высокая. Для веба нужно еще меньше разных деталей, объектов, текстур. И главное, по умолчанию в игре стоят средние настройки в которых есть тени и post process AO сильно нагружающие систему. Наверняка дети даже не заходят в настройки что бы сменить графику. По умолчанию лучше ставить низкие настройки графики, на низких в большинстве случаев игра будет идти плавно.
Обучение в игре. Зачастую обучение важно, но в данной игре этому практически посвящён целый уровень. Сейчас дети привыкли к тиктокам, им нужен ежесекундный контент. Тем более это браузерные игры, их можно переключить очень быстро и без установки. Хорошим вариантом для обучения будут подсказки не обрывающие игру, причем важно с первой же секунды дать игроку весь самый интересный геймплей.
Вес игры. Хоть всё и хорошо ужато, деталей много. Сейчас вес составляет 45 мб. В среднем загрузка у игроков составляет 18 секунд. Я считаю, желательный вес до 25 мб, загрузка до 10 сек. для аналогичной игры.

Метрики, две недели после релиза.
После обновления
Я сделал обновление, в котором исправил проблемные моменты.
Результаты:
После запуска первого тренировочного уровня выключали игру 22% игроков, теперь 18%.
Там, где уходили 50% игроков, теперь уходят лишь 4% .
Следующие триггеры:
Было 13%, стало 5%.
Было 30%, стало 4%.
И т.д…
Что касается доходов игры и её продвижения на площадке:
По посещаемости график немного растёт вверх, но это может быть связано с чем угодно. Тут не следовало ждать сильных изменений, ведь обложка игры не была заменена.
Плейтайм на игрока вырос с 10 минут до 13-ти.
Доход вырос с ~50р в день до ~100р.
Вывод можно сделать однозначный — метрики могут хорошо показать проблемные места игры, которые можно успешно устранить.
Сделать такие метрики на самом деле очень просто. Как вести такой же анализ:
Есть понятная и расширенная информация об этом в документации PluginYG (Раздел «Яндекс Метрика»). Там понятно описано как внедрить такие же метрики.
Как я получал такие цифры в процентах:
Например, в игре есть триггер 1 и триггер 2, которые отображаются в метриках в цели triggers. На первом триггере 600 визитов игроков (значит до этого момента дошли 600 игроков). На втором триггере 500 визитов. На любом сайте находим разницу двух чисел в процентах. В данном случае разница получается 16.67%. Значит между первым и вторым триггерами ушло 16,67% игроков.

Метрики после обновления
Заключение
Метрики — очень полезная штука, и совсем не сложная в использовании. Если, конечно, с плагином и документацией к нему.
Подписывайтесь на меня и на мой телеграм, чтобы узнавать такие полезные новости первым. Я так же буду делиться и очень полезной информацией, и очень срочной! Да, срочность, это один из самых главных факторов успеха, когда нибудь и об этом напишу.
Показать полностью 2
13 дней назад

Атмосферно получается?
Сделал небольшой прототип. Есть мысли наделать разных окружений, технику, лебёдку, грязь. Ну и какой-то смысл самих поездок тоже добавить.
16 дней назад

Написал свою первую игру для Dendy (NES) — The Iron Steam

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

Логотип консоли Dendy
История создания игры
Идея создать свою собственную игру для денди появлялась у меня довольно давно, но плотно занялся я этим вопросом только в конце 2022го года.
Основным стимулом для разработки игры послужило мое желание создавать свои модули расширения для консоли, так как для денди их практически не выпускалось, а у меня по этому поводу есть много идей и планов (модуль подключения обычно клавиатуры, модуль выхода в интернет и т.д.).
Изначально была поставлена задача написать хотя бы «Hello, World», который я мог бы запустить на эмуляторе. Но, начав читать переводной курс по разработке игр для денди на языке Си на хабре, мне удалось написать простейшую программу всего лишь за полчаса. И этого мне показалось слишком мало.
Более-менее освоив курс статей с хабра за 2-3 недели, в конце января 2023го было принято решение разработать пошаговую стратегию про стимпанковых мехов для закрепления навыков. Думал, что ограничусь созданием минимального геймплея, но разработка зашла немного дальше.
Такой сеттинг и жанр я выбрал, так как люблю пошаговые стратегии, стимпанк и игры про мехов (фронт мишн ван лав). Тем более у меня были наработки на эту тему в плане механик и немного лора (я делал наброски подобной игры для современных компов, но забросил).
В итоге с начала февраля 2023го началась активная разработка игры и продолжалась она до середины апреля (далее у меня появились более важные дела и игру пришлось отложить до лучших времен).
Игру я хотел анонсировать еще летом, так как базовые механики уже работоспособны и она проходима (хотя конкретно концовки у игры нет, можно просто пройти все уровни и прокачивать меха). Есть даже примерочный открытый мир, но он будет полностью перерисован и доработан.

Скриншот боевого геймплея актуальной версии игры
Особенности разработки игры для Денди
Разработка игр для NES/Famicom консолей является крайне специфическим занятием, так как требует понимания работы приставки на аппаратном уровне, что для многих является отталкивающим фактором. Но, так как у меня есть опыт разработки софта для микроконтроллеров, эта особенность для меня была не слишком критична.
Далее стоял вопрос о инструментах для разработки игры. Традиционно игры для денди пишут на ассемблере, так как ресурсы консоли очень ограничены и важен каждый такт процессора и каждый байт памяти. Я мог бы писать и на ассемблере, но это затянуло бы проектор и увеличило шансы к его забрасыванию на свалку истории.
В итоге я выбрал компилятор CC65, который позволяет писать код для денди денди на языке си. Этот компилятор поддерживается до сих пор и регулярно выходят обновления.
В качестве среды для разработки я выбрал Visual Studio Code. Для удобной сборки и запуска проекта был написан батник и добавлены горячие клавиши (но это тоже тема для отдельного поста). Так я собираю проект и запускаю его в эмуляторе нажатием одной клавиши на клавиатуре.
Глубоко закапываться в технические особенности консоли и разработки под нее я не хочу, так как ресурс все-таки развлекательный. Хочу отметить только несколько основных особенностей.
Вся графика состоит из тайлов 8х8 пикселей. При этом каждый тайл может использовать только 3 цвета и один прозрачный цвет (прозрачный цвет отображает цвет фона, а цвет фона определяется определенными битами регистров палитр).
Это значит, что требуется сводить все используемые спрайты к трем цветам, но если если спрайт состоит из нескольких тайлов, каждый тайл может использовать разные палитры (примерно так же это работает и для фона, но там немного сложнее).
Поэтому, если вы хотите вывести случайную картинку в формат NES, то ее нужно свести в формат 4 цветов и до нужно разрешения (256×240 пикселей). Вот пример преобразования картинки в формат, который уже можно вывести в вашу игру:

Реальное фото я преобразовал в денди формат (фото использовано с разрешения автора)
Подготовку изображения в почти автоматическом режиме легко сделать в фотошопе или гимпе (я использую гимп).
Но самая сложная часть разработки — это рисования пиксель арта в условиях очень низкого разрешения и ограниченности в количество цветов.
Для первых версий игры я использовал готовые спрайты из Front Mission без дополнительной подготовки. Они выглядели так себе, так как игра выходила на 16-битных консолях. Вот так это выглядело:

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

Скриншот режима битвы одной из ранних версий игры
На скриншоте выше видно, что трава действительно вышла даже немного симпатичная и в меню я тогда использовал некрасивые рамки.
Помимо режима битвы в игру был добавлен режим открытого мира. Карту мира я набросал довольно быстро и больше ее особо не переделывал. Выглядит она на данных момент вот так:

Временная карта мира
На карте мира каждая локация обозначена постройкой и войти в нее можно с помощью нажатия кнопки «A» на геймпаде. Локация в верхнем-левом углу — это локация-хаб с магазином, а остальные запускают сценарий битвы при входе (в каждой локации разный набор врагов, они отличаются комплектацией мехов и их количеством).
После того, как основные механики были реализованы, был начат процесс перерисовки мехов.
Как я уже говорил, одновременно можно использовать 3 цвета и один прозрачный цвет, который использует цвет фона. 3 цвета на при разрешении 16х24 пикселя на одно меха — это очень мало.
Поэтому я использовал решение, которое дало мне дополнительный цвет. Для этого я отказался от травы на экране и залил весь экран черным фоном. Это дало мне черный четвертый цвет для рисования мехов. Т.е. если я делаю прозрачный пиксель в спрайте, он выглядит как черный. Это позволило нарисовать более-менее адекватных мехов, которые выглядят как мехи. Вот так это выглядит в редакторе:

Спрайты мехов с использования прозрачных пикселей с черным фоном
Уже намного интереснее, но для анимации ходьбы нужно нарисовать для каждого положения по два спрайта (этим я пока не занимался, так как такой мелкий пиксельарт приходится рисовать буквально по пикселю, это очень муторно).
Многие технические ограничения консоли можно обойти за счет использования мапперов, но я пока обхожусь без него, так как хочу сделать создание реального картриджа максимально дешевым и простым. Стараюсь уложиться в стандартные 32 килобайта (место я потратил еще не все, музыка и прочее туда должно поместиться, тем более многое можно оптимизировать).
Резюмируя особенности разработки, можно сказать, что разработка игр для ретро-консолей особо ничем не отличается от разработки программ для микроконтроллеров. По этой причине постоянно приходится смотреть даташиты, описывающие разные узлы консоли.
Механики и ЛОР игры
Игра представляет собой классическую пошаговую стратегию, основанную на механике использования очков действия (AP). Каждое действие тратит очки действия, примерно как в лучшей в мире игре Fallout 2 (только у меня клетки квадратные). Система с фазами (как в X-COM) мне нравится меньше.

Панель, которая отображает состояние деталей меха и количество очков действия.
В режиме битвы игрок управляет своим мехом и пытается уничтожить вражеские мехи. Мех считается уничтоженным, если он лишается тела или обеих рук (без рук мех бесполезен). При этом, если мех лишается головы, он сильно теряет в точности, а если у него взрываются ноги, то он не может передвигаться. Битва заканчивается уничтожением всех вражеских мехов или гибелью игрока. Если игрок побеждает, он получает деньги за каждую сохраненную деталь вражеского меха.
Все оружие в игре делится на 4 типа:
- Рукопашное оружие (может атаковать на одну клетку и есть возможность выбора точки атаки)
- Пушки (наносят урон по случайной части меха с расстояния)
- Снайперское оружие (наносят урон с расстояния и имеют возможность выбрать деталь вражеского меха для атаки)
- Дробовики/картечницы (наносят урон по нескольким случайным частям меха)
- Возможно будут еще какие-то типы оружия.
Вот пример меню выбора части меха для атаки:

Меню выбора части меха для нанесения по ней урона
Еще есть режим осмотра мехов (отображает имя, состояние частей меха и вооружение):

Режим осмотра меха, очки действия не тратит (Но может должно тратить?)
В режиме перемещения вы перемещаете меха курсором (каждый шаг тратит одно очко AP). Кнопка ‘A’ подтверждает перемещение, а кнопка ‘B’ возвращает меха на начальную точку (отменяет перемещение).
Механика использования экипировки пока не реализована.
Следующей важной частью игры является прокачка меха.
Вот так выглядит список доступных мест в локации-хабе:

Выбор места для посещения в хабе
А вот для примера магазин оружия:

Кнопка А покупает оружие в правую руку, В в левую, а Select возвращает вас на карту мира.
Вот мы и рассмотрели все основные особенности игры. Остальное вы можете попробовать сами используя эмулятор (ссылку на скачивание эмулятора и рома игры я дам в конце, если пикабу ссылки не уберет).
Планы по развитию игры
Планов по развитию игры у меня довольно много. Давайте приведу основные планы в виде списка:
- Создание нормальной карты мира и проработка локаций на ней
- Динамические анимации движения мехов в режиме битвы
- Создание возможности ходить персонажем по хаб-локации и общаться там с людьми (но это сильно упирается в 32 килобайта памяти)
- Написание лора с сюжетом и добавление его в игру
- Создание диалоговой системы
- Добавление звуков и музыки в игру (музыка на денди особенно специфическая штука)
- Добавление новых спрайтов для мехов
- Добавление различных построек и препятствий в режиме битвы (для оживления поля битвы)
- Улучшение ИИ и добавление новых механик в битву
- Расширение количества доступных частей и оружия для мехов
- Режим игры для двоих игроков (PvP и PvE)
Для первого поста и анонса игры, я думаю, информации более-чем достаточно. Очень жду ваших предложений и замечаний по игре. Весь этот текст был написан в первую очередь ради получения обратной связи от потенциальных игроков, так как я не могу знать, что нравится другим людям, а исходить только из собственных соображений — это путь в никуда.
Поэтому жду вас в комментариях, готов ответить на все ваши вопросы. Спасибо за внимание.
Список основных ресурсов, которые я использовал при разработке:
- Цикл статей по разработке игры для денди — https://habr.com/ru/articles/348022/
- Википедия по разработке для NES (там все оч подробно описано и с примерами кода, но английским) — https://www.nesdev.org/wiki/NES_reference_guide
- Живой форум по разработке ретро-игр (и не только) — emu-land.net
- Сайт компилятор СС65 — https://www.cc65.org/
- Еще несколько хороших статей про устройство консоли (на русском) — http://dendy.migera.ru/nes/g00.html
- Эмулятор который я использую для отладки игры — fceux.com
- Страница проекта. Там можно скачать ROM-файл для эмулятора (Нужно ли делать отдельный паблик для игры?) — http://73-it.ru/the-iron-steam.html
Видео-версия статьи с геймплеем и моими комментариям
Показать полностью 12 1
Поддержать
16 дней назад

Доделать игру и умереть — опыт основателя студии perelesoq
Две недели назад вышла наша игра Torn Away. Мы начали делать её в далёком 2019 году, в то время, когда трава действительно была зеленее. Что же я чувствую сейчас, спустя эти долгие 4 года?

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

Да, тогда журнал ещё печатали на бумаге
Позже в одном из выпусков журнала Игромания я прочитал, что есть такая профессия — 3D-моделлер. Делать модельки и рисовать текстуры звучало гораздо интереснее. Так я начал скупать книжки по моделлингу, зависать на сайтах вроде рендер.ру и других форумах.

Интерес к 3D начал потихоньку пропадать — то ли усидчивости не хватало, то ли результаты перестали радовать — но зато меня увлекло рисование от руки. На один из дней рождений родители подарили мне планшет Ваком Бамбу. С него и начался мой путь в мир 2D-арта.

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

Одна из старых работ
Так я более-менее понял, куда мне нужно двигаться, чтобы делать игры. Ещё через пару лет, на летних каникулах я познакомился с арт-диром небольшой команды, она позвала меня к ним рисовать казуалки. Это был 2011 год, индустрия как раз наполнилась играми в соцсетях… В общем, я был безумно рад такой возможности. С этого момента можно отсчитывать мой путь в геймдеве.

Мой уровень на тот момент
Проработал я там всего несколько месяцев, потому что совмещать парт-тайм работу с учебой в 11-ом классе было трудновато. Тем не менее, в школу я уже ходил только для галочки. Меня всё больше и больше увлекала графика. Я много рисовал для себя, придумывал какие-то сюжеты, истории, ситуации…
Мне 18 лет. Заканчиваю школу и уезжаю в Москву. Несколько месяцев ищу работу, активно делаю тестовые задания. В какой-то момент казалось, что я переоценил свои возможности и никому такое юное дарование не сдалось.
И вот долгожданный звонок — меня берут в крупную по меркам времени компанию, которая занимается социалками и мобилками. Отлично, иду работать в офис и получать настоящий боевой опыт бок о бок с ветеранами индустрии.

Иллюстраций с тех времён я не нашёл, зато откопал такое!
Все ребята, с которыми я познакомился, были реально крутыми. Но чем дольше я там работал, тем сильнее я чувствовал тесноту в рамках профессии художника. Да, мне всё ещё нравилось рисовать по своим идеям, но реализовывать чужие… Я понял, что пора создавать что-то своё.
…и ушёл из игровой индустрии ради работы с интернет-сообществами. Эта сфера подкупила меня тем, что можно было довольно быстро реализовать идею и почти мгновенно получить отклик от сотен, а то и тысяч человек. Если кто-то из вас помнит 2012-2013 год, когда паблики в ВК были местом андерграундного творчества, то вы меня поймёте! Этот опыт может показаться совсем сторонним, но только на первый взгляд.

Как же хорошо было тогда в Интернете!
Зарабатывая в другой сфере, я начал думать о том, чтобы вернуться в разработку, но уже самостоятельно. Программировать я по-прежнему не умел, поэтому принялся искать напарника. Всего через пару недель карты сошлись и мы начали общаться с парнем, который тоже хотел вкатиться в геймдев. У него было много прототипов, но не было законченных идей.
Всё случилось очень быстро: потратили пару дней на обсуждение, выбрали наиболее интересную из его наработок, я сочинил концепт и нарисовал всю графику. Четырнадцать дней и вот игра уже в Аппсторе.

Тут оказались кстати мои паблики в ВК. Благодаря ним мы смогли дотянуть до топа Аппстора. Денег мы тогда никаких не заработали, но зато получили крутейший опыт.
Конечно, я мечтал не о таких играх — а о тех, что захватывают своей историей и долго не отпускают после прохождения. Можно ли было сразу начать с таких? Наверное, можно. Но я не советую. Сейчас ретроспективно понимаю, что начинать нужно с малого, иначе есть риск стать жертвой амбиций — так и остаться тем самым фантазёром, у которого тысяча крутых идей, но ничего даже не записано на бумаге.
За несколько лет я сделал ещё несколько небольших игрушек. Успел поработать геймдизайнером, подрос до ПМ, а затем и до продюсера. Выгорел, бросил всё и при этом сделал игру (почти) в одиночку.

В моей жизни была не только самостоятельная разработка. Появились крутые карьерные возможности, своя семья и обязательства, а вместе с ними предательская мысль: не пора ли заканчивать это баловство? Наши большие мечты часто не умещаются в обычную жизнь. Может пора просто повзрослеть?
Пока я размышлял над этими вопросами, судьба подкинула мне возможность. Через общего друга я познакомился с одним парнем, которого очень интересовала индустрия игр. Он сам большой поклонник проектов с глубоким нарративом, но все в его окружении были повёрнуты на метриках и способах поизысканнее вытащить из игроков денег. Наши взгляды на то, какими должны быть игры, совпали.
Уже через неделю я вернулся с небольшим документиком, в котором описал концепцию игры. Моему новому товарищу идея понравилась, и он дал добро на сбор команды. С этого началась история Torn Away.
(Кстати, узнаёте голос нарратора?)
Dпервые за свою жизнь я оказался так близок к той самой мечте из детства. Сделать такую игру, которую тому самому школьнику было бы интересно пройти вместе со старшим братом… Ничего не пугает так сильно, как страх превращения мечты в реальность. Что будет, если у меня не выйдет? Что будет, если выйдет, но это никому не понравится? Почему я вообще решил, что мне есть, что сказать?

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

Примерно так порой ощущалась разработка. Сама игра на русском, другого скрина под рукой нет)
Было столько удобных причин сдаться — ну да, не вышло. Так сложилось. Но всё же почему-то, раз за разом, мы брались за дело и делали всё, что от нас зависит.
Для себя я выделил две причины. Первое — это любовь к делу, погоня за мечтой. Вторая — ответственность перед командой, которая вложила столько труда в наш общий проект. Варианта отступить для меня просто не существовало.
Подводя итог, хотелось собрать здесь несколько выводов, которые я для себя вынес за все эти годы. Возможно, они окажутся полезными кому-то из вас. Самому себе 4 года назад я бы точно сказал это:
- Если нет опыта, то начни с малого. Иначе рискуешь никогда не доделать
- Люби то, что делаешь. Если твоя игра провалится, ты не будешь жалеть о бесполезно потраченном времени
- Чем больше твоя команда, тем яснее должно быть твое видение. Научись формулировать!
- Если делаешь сюжетную игру, либо пиши сам, либо делай сценариста полноценной частью команды
- Не работай в стол — реакция игроков это безумно важно. Долгое время будет казаться, что всё, что ты делаешь, никому не нужно. Реальные игроки помогают понять, что это не так
- Разделяй ответственность, работа в команде это в том числе про доверие
- Береги тех, с кем работаешь. Да, всегда хочется прыгнуть выше головы, но погоня за совершенством изматывает людей
- Веди документацию, планируй задачи. Это не убивает душу, а спасает нервы и бережет время
- Фиксируй рабочие отношения юридически, перед заключением договоров найми юриста
- Всё обязательно пойдёт не так, как ты задумал, будь к этому готов
- Держи режим дня, хорошо питайся и спи
- Сделай сначала хоть как-нибудь, потом постепенно улучшай. Хорошее рабочее решение гораздо лучше идеального теоретического
- По возможности, работайте в одном пространстве. Это поможет вам сблизиться и не возненавидеть друг друга во времена трудностей

Отвечая на вопрос в начале текста: что же я чувствую, выпуская игру, на которую ушло 4 года моей жизни — я чувствую много всего.
Удовлетворение от законченной работы. Гордость за всех ребят, с кем посчастливилось трудиться вместе. Волнение за то, как игроки по всему миру примут историю Аси — наше маленькое и грустное приключение. Предвкушение того, что ждёт впереди. И благодарность. Пожалуй, благодарность — это самое сильное чувство.
Я благодарен моему партнёру за то, что поверил в меня. Благодарен всей нашей команде за преданность общему делу и невероятный талант. Благодарен нашим игрокам — за то, что следите за нами все эти годы и пишите много теплых слов. Всем нашим издателям за помощь в донесении нашей игры до широкой аудитории. А ещё я благодарен своей любимой жене — за терпение, поддержку и вдохновение.
И всем, кто дочитал до конца!
Для тех, кто желает нас поддержать покупкой, оставлю ссылки на Steam и VKPlay. Игра также вышла на Xbox, готовимся к релизу на PlayStation и Nintendo Switch.
Показать полностью 14 2
3 месяца назад

Первые попытки освоить движок Godot — делаем простой платформер

Уже неделю моя гоблинская тушка не подавала признаков жизни на Пикабу. Все кто думали что я сдох — не дождетесь, я мудитировал и искал знания в молитвах Горку и Морку. В переводе на человеческий — смотрел и читал обучающие материалы по Godot.
Проблема состоит в том, что проще выдать замуж троллиху, чем найти годный и главное понятный материал по данному движку на русском языке. Конечно, есть какие то азы, но дальше чем кривое управление платформера они не уходят, либо уже мне как новичку становится непонятно.
На помощь приходит всеми любимый зарубежный Ютуб и переводчик видео от Яндекса, наткнулся на пару каналов где информацию доносят более-менее доходчиво. И так, чему же я научился за эту неделю?

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

Все мы иногда статичное тело.
Правой кнопкой мыши жмякаем на нашу 2D сцену «World» и выбираем «Добавить дочерний узел». В списке ищем «StaticBody2d» и теперь у нас есть база. Добавляем два дочерних узла уже в статичный объект — «Polygon2D» и «CollisionPolygon2D».
Для тех кто не понимает на басурманском — объясню, что есть что. Первый — это визуальная геометрическая фигура, а второй — область столкновения (collision — столкновение). Все это нужно для того, чтобы мы могли увидеть наш объект, а игрок не проваливался внутрь него при столкновении.

Рисуем будущую карту при помощи CollisionPolygon2D.
При помощи области столкновения мы наметим будущую карту. Для того чтобы ее было проще рисовать — сделаем привязку к сетке, а далее добавляем по клеткам метки. Должно получится нечто схожее со скриншотом выше.

Код приравнивающий форму фигуры к форме области столкновения.
Теперь нам нужно сделать так, чтобы визуальная фигура повторяла форму области столкновения. Нажимаем на нашу сцену и добавляем к ней скрипт. GD-script во многом схож с языком Python и более-менее прост в понимании. Сначала добавим наши узлы в виде переменных, для этого зажимаем «ctrl» и перетаскиваем в код после блока extends.
Прописываем функцию ready, она будет воспроизводится сразу во время запуска сцены. А дальше просто приравниваем форму фигуры к форме области столкновения (polygon_2d.polygon = collision_polygon_2d.polygon).

Получаем дешевую и сердитую карту — все в гоблинском стиле!
Карта готова, но что делать теперь? Пора добавить нашего персонажа-марионетку.
Создаем новую сцену и для ее основы берем узел CharacterBody2D. Для будущей простоты восприятия я переименовал его в Player. Чтобы увидеть нашу тушку — добавим к ней дочерний узел «Sprite2D», а чтобы можно было еще и потрогать «CollisionShape2D».


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

Наши переменные.
Задаем переменные через const (constants — постоянное значение). Значения констант не могут быть изменены в ходе самой программы, на то они и постоянные. Для чего нужны эти значения расскажу ниже.
const SPEED = 150.0
const JUMP_VELOCITY = -300.0
const FRICTION = 1000.0
const ACCELERATION = 600.0
На этот раз мы берем не функцию ready, а другую — physics_process. В отличии от простого process, здесь время между выполнением функции будет одинаковым. Это обеспечит нам стабильность при передвижении объектов.
Начнем с настройки гравитации!
Дело в том, что система координат X-Y в Godot имеет свои приколы. Ось X идет от отрицательной к положительной слева направо, однако ось Y идет от отрицательной к положительной сверху вниз. То есть ось Y буквально перевернута с ног на голову. Если непонятно — объясню проще:
Хотим передвинуть вправо — прибавляем к оси X;
Хотим передвинуть влево — вычитаем из оси X;
Хотим передвинуть вниз — прибавляем к оси Y;
Хотим передвинуть вверх — вычитаем из оси Y;

Гравитация. беспощадная ты с*ка!
Как же нам заставить персонажа падать под давлением гравитации? Для начала добавим переменную GRAVITY равную 1000. Затем создаем свою пользовательскую функцию и называем ее aplay_gravity.
Мы должны падать когда находимся в воздухе, то есть не на полу. Буквально говорим программе «Если объект не на полу сделай следующее: измени положение по оси Y в положительную сторону на заданное нами расстояние».
if not is_on_floor():
velocity.y += GRAVITY * delta
Что такое delta? Это время между кадрами, благодаря чему перемещение будет стабильным вне зависимости от FPS.
velocity — это параметр скорости изначально зашитый в наш объект. По этой причине его так же не требуется объявлять как переменную. Грубо говоря сюда мы задаем то расстояние, на которое должен переместиться объект по осям X и Y.
Так как мы каждый раз увеличиваем прошлое значение velocity.y, гравитация будет усиливаться с каждой секундой в воздухе. Благодаря этому у нас не получится прыгать бесконечно вверх и нас прижмет к полу.

Отлично, нас прижало как после «Балтики 9»!
Теперь настраиваем прыжки!
Для этого создаем еще одну пользовательскую функцию handle_jump. Мы говорим ей: «Если мы нажимаем кнопку прыжка и находимся на полу — измени положение по оси Y в отрицательную сторону». Напомню, что константа прыжка имеет отрицательное значение.
if Input.is_action_just_pressed(«ui_accept») and is_on_floor():

К гравитации добавляются прыжки.

Прыжок веры.
С прыжками и гравитацией мы освоились, теперь научимся ходить-бродить!
Надеюсь вы еще не забыли, что направление у нас зависит от отрицательного или положительного значения? Есть такая штука в Input как get_axis, где мы задаем две клавиши. Нажатие первой клавиши прировняет переменную к значению -1, нажатие второй клавиши наоборот к 1. Если ни одна из клавиш не нажата, переменная принимает значение 0.
Создаем переменную input_axis внутри physics_process, на этот раз через var, ведь она будет менять свои значения в процессе. А далее задаем машине установку «Если нажата одна из двух клавиш, то мы меняем значение по оси X в зависимости от выбранного направления».
Для этого используем move_toward, где первое значение — наша начальная точка, второе — конечная точка, а третье — промежутки которые будут проходится для их достижения.
Начальная точка — velocity.x
Конечная точка — наша скорость SPEED помноженная на направление (-1 или 1)
Промежутки — наше ускорение ACCELERATION помноженное на время между кадрами delta
if input_axis !=0 :
velocity.x = move_toward(velocity.x, SPEED * input_axis, ACCELERATION * delta)

Вот наш код.

А вот признаки жизни. беги Форест — БЕГИ!
Двигаться мы можем, а вот с остановкой проблема. Что не дает нам вечно кататься по земле? СИЛА ТРЕНИЯ!
Для того чтобы создать силу трения мы делаем похожую функцию. Только теперь конечной точкой у нас выступает 0, а вместо ACCELERATION берем параметр FRICTION. Включается все когда мы не нажимаем кнопки движения, то есть input_axis равен нулю.
if input_axis == 0 :
velocity.x = move_toward(velocity.x, 0, FRICTION * delta)


Бегаю, никого не трогаю. к земле притягиваюсь во время прыжка.
Вишенкой на торте внутри физической функции является move_and_slide которая и отвечает за все эти процессы. Без нее указанные выше шаманские обряды просто не запустятся.
Получился максимально простой гоблинский платформер. Конечно, это пока сложно назвать игрой. но оно работает во славу Горка и Морка! В данном посте я рассказал лишь основы изученного, благо материал заготовлен почти на месяц вперед.
Надеюсь для тех кто в первый раз сталкивается с Godot данный пост будет хоть немного полезен, а более опытные орки и гоблины знатно посмеются с попыток новичка вкатиться в разработку игр.
Если вам интересно и дальше смотреть на то как я собираю лбом грабли, а может и самим чему-то научиться вместе со мной — подписывайтесь на данный блог!
Вот так полностью выглядит код управления персонажем, если кому то нужно для ознакомления.


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

Я делаю еееееегры :)))
Ну, и всякие картинки пилю тоже время от времени, но это вы уже в курсе 🙂
А это моя старая и чуть более брутальная работа 😉


Показать полностью 3
5 месяцев назад

Первый тизер Тридевятьземель
Наконец-то собрали приемлемый тизер для игры.
6 месяцев назад
Сделал бесплатную игру для iOS без рекламы и донатов

Играется горизонтально, вертикально, с геймпада, с сенсора, как угодно.
Игра небольшая, жанр не особо знаю, это и не гонки, и не тайм-киллер, бывает сложно, бывает легко.
Игра небольшая, но надеюсь, что получилось, как минимум, неплохо.
Если понравится, добавлю таблицу рекордов с онлайном!
Движок — Godot Engine
Показать полностью
9 месяцев назад

Мой первый месяц в Godot Game Engine
В начале года решил попробовать освоить Godot. Навыков программирования у меня было 0, знал только что есть циклы for i=чет там и тд и тп, которое я проходил в университете на delphi.
Почему выбор пал на Godot? Где то прочитал, что GDScript который используется в годоте не такой сложный язык и новичкам программирования будет не так трудно (но я не новичок, я просто тупой в программировании и код вижу примерно вот как на следующей картинке)
(Картинка замылена в фш, а не не прогрузилась)

Начинал я с оффициальной документации Годота.
Там есть глава где по пунктам тебе пишут как делать свою первую игру, в которой тебе нужно передвигаться и уворачиваться от врагов, которые спаунятся за экраном.
Это мы пропустим, так как любой сможет ее сделать, прописано всё там очень подробно.
Далее я стал искать разного рода туториалы на ютубе. Всякие полезные ютуб каналы и просто статьи я искал в посте, который подготовил пикабушник @wolchy, пост: Godot Engine. Библиотека новичка
В одной из ссылок я нашел туториал, как сделать top-down shooter. После этого туториала я решил сделать что то своё, так как хотелось сделать тоже шутер с видом сверху, но чтобы стрелять можно было во все стороны, а не только вперед(вверх).

Чтобы сделать такой шутер я искал разного рода туториалы. Как сделать правильно движение игрока, как сделать стрельбу, проджектайл, врагов спаун и тд.
Первая версия получилась такой: статичный экран, бластер, один тип врагов.
Один товарищ с дискорда решил сделать взлом жопы игры и крашнул ее.
Никаких увеличения скорострельности в игре нет Т_Т

После я попытался сделать клон флаппи бёрд. Делался он по нескольким туториалам, так что особо интересного в этом нет, флаппи берд видели все.
Из нового я сделал запоминание highscore и сделал так что со временем проем в стенках становится всё меньше и меньше.
Следующее что я хотел сделать, это одну идею, которую я реализовывал бы уже 3ий раз, предыдущие 2 раза я реализовывал в других конструкторах для игр.
Tile Game демка на 6 уровней.
Когда то я эту идею увидел в интернете и решил повторить, теперь вот сделал ее в Годоте.
Суть игры проста, при нажатии на плитку, она двигается в направлении стрелки.
Плитка может двигать другие плитки.
Задача: сопоставить все плитки с точками на поле.

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

Далее я решил вернуться к своему шутеру. Я решил сделать так, что это будет тест игрой для внедрения различных механик до той степени пока у меня не будет спаггети код или мусорная свалка из плохо сортированных ассетов.
Из нового:
— Сделал нестационарный экран
-Добавил уклонение (дэш на корабле? я че дурак)
-Добавил бомбу, у которой есть куллдаун
-Внедрил сохранение highscore
В планах научиться делать смену оружия, возможно даже колесо выбора оружия.
Новые виды врагов, может быть даже другие уровни.
Попробовать сделать магазин апгрейдов или оружия.
Все полученные знания из этой игры применить на новой игру.
В данный момент пытаюсь сделать платформер с дробовиком.
Суть платформера будет заключаться в том, чтобы пройти уровень собрав 2 типа коллектаблов (собираемых предметов) и сломать другой вид коллектаблов с ружья.
Игрок уже может прыгать, делать двойной прыжок, стрелять, скользить вниз по стене и прыгать от стенки к стенке.
Так же на этом платформере тренируюсь использовать анимационные спрайты и разного рода другие функции Годота.
Это будет такая полушутливая игры для дискорда, у меня на нее некоторые планы.

Не уверен по поводу постинга ссылок, поэтому воздержусь.
Шутер опубликован на itch io. Может будет пробиваться по поиску, не знаю.
В общем это мой первый месяц в годоте. Посмотрим как оно будет продолжаться.
В одном из конструкторов я проработал над одной игрой 1.5 года почти в одиночку и немного перегорел. И того же запала как раньше уже нет. Но зато теперь я могу выложить игру в дискорд и люди не имеющие PS4 смогут поиграть на компьютере.
Как то так. Пока нравится, но обучение трудный процесс.
Показать полностью 6 2
9 месяцев назад
Исповедь разработчика #5. Снова в бой!
Привет всем! Меня зовут Пётр, и это новый виток развития моих навыков разработки игр!
П В прошлых постах я рассказывал об успехе игры «Бункер 21» и моём личном «крахе» из-за неверного управления финансами, собственной недальновидности и сложившихся обстоятельств, которые я никак не мог предугадать, или не желал признавать, и, как следствие, вовремя не среагировал на изменяющуюся обстановку, что и привело к довольно печальной ноте, на которой всё окончилось.

Бросил ли я разработку игр? Конечно же нет!
Да, я какое-то время пребывал в прострации и пытался осмыслить сложившуюся вокруг меня реальность, чтобы как-то отталкиваться для движения в будущее.
Было довольно сложно заставить себя хоть что-то делать, но, не зря говорят, что аппетит приходит во время еды.
Хандра начала отступать.
Сначала работа давалась с трудом, приходилось пересиливать себя, но, главное в рабочем процессе — начать что-то делать.
Постепенно я начал восстанавливать рабочий ритм.

Недавно искал подработку, писал здесь пост, но столкнулся с волной негатива и высмеивания, дескать, как так могло получиться, что такой успешный я так круто «приземлился», что готов браться за подработки? Ну вот так и могло, не сидеть же на жопе в ожидании чуда.
Итак, новый проект — Убежище 23.
Разумеется, я начал шагать по уже протоптанной дорожке — мобильная игра.
Обновлённое ядро игры, совершенно новые шейдеры для графики, плавная камера, много оптимизаций и разных нововведений.
Цель — создать интересную историю на базе несложной графики.

Сюжетно проект существует в рамках созданного в «бункере» мира. Хочется захватить как новую аудиторию, так и старую. После большого успеха основной игры, было бы глупо не воспользоваться такой возможностью. Да и мне однозначно есть что рассказать, «вселенная» там довольно объёмная.
На текущий день (24 января 2023) над игрой я работаю 3 месяца, а опубликована в Google Play она была 2 месяца назад.
За это время игра на «органике» начала получать в среднем по 200 установок в сутки.
Сначала по 10, потом по 50, и так по нарастающей с интервалом в неделю-полторы.
Так выглядит статистика установок за последние 30 дней:

Как можно заметить, растёт график установок нестабильно, иногда проседая, но общая картина довольно позитивная.
Также игра вышла в топ Google Play в категории «Приключения» на, примерно, 400 место, что довольно занятно. Бункеру, чтобы попасть в топ-500 игр потребовалось больше года, но на это были причины, разумеется.
В App Store игра очень сильно скачет, иногда она может находиться в категории «Приключения» на 15 месте, а иногда на 120. Причём временная разница между этими двумя позициями может быть в несколько часов.

По длительности прохождения сейчас в игре есть две главы, суммарно которые можно пройти за 25-30 минут. За это время игроки успевают посмотреть немного рекламы.
За первый месяц после релиза игроки «насмотрели» её на 1000 рублей примерно.
За второй месяц, так как увеличилось количество установок, уже на 3000, а за третий подсчёт ещё идёт.

В среднем за сутки игра приносит от 200 до 400 рублей. Реклама используется от рекламной сети Яндекса (РСЯ).
Вот такая аналитика получается. Спасибо всем, кто пишет хорошие слова поддержки, а так же пишет отзывы.
Я видел несколько отзывов от ребят, что писали «Привет с Пикабу». Если вы сейчас здесь, то и вам привет! Я буду стараться и дальше!
PS: иногда ловлю вопросы о том, на каком движке делаю — это Godot Engine.
Показать полностью 6
10 месяцев назад

Выпустил демо-версию своей стратегической игры Citadelic, разработанной в одиночку
Citadelic — стратегическая игра с элементами roguelite. Защищайтесь от набегов постоянно меняющихся врагов, одновременно расширяя свою базу и управляя ресурсами. Принимайте решения и адаптируйте свою стратегию, учитывая слабые стороны противника.
Игру разрабатывал примерно 4 месяца на собственном игровом движке. Сначала появилась идея об игре-стратегии, сделал экспериментальный прототип и начал развивать дальше.
Разработкой занимался по вечерам и на выходных. Процесс разработки можно разделить на этапы, на каждый уходила примерно 1 неделя:
— Прототип игры: можно строить здания и отбиваться от врагов
— Развитие прототипа: эксперименты с новыми механиками игры, интерфейс, разновидность врагов и турелей, апгрейды для зданий, добыча ресурсов и т.д.
— Планирование дальнейших шагов: продуманы типы зданий, балансировка, типы и разновидности врагов, ресурсов и т.д.
— Разработка системы эффектов
— Создание и балансировка алгоритмов генерации врагов. Враги постоянно «мутируют» и улучшаются, меняются в своих характеристиках.
— 3D графика — модели, текстуры и анимации для всех зданий и типов врагов
— Дополнительные элементы игры: выбор случайных наград, дополнения к зданиям, «способности», которые можно применить во время боя, и т.д.
— Написание музыки и звуковых эффектов
— Перевод текстов (поддерживается английский и русский) — всего около 900 строчек текста
— Создание трейлера, скриншотов, оформление страницы игры в Steam
— Всё остальное время: дополнительное тестирование, балансирование, «полировка», улучшения в интерфейсе.
Демо доступна в Steam (добавьте игру в список желаний, если понравилась): https://store.steampowered.com/app/2248390/Citadelic
Показать полностью
10 месяцев назад

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


И новую рубку деревьев:

И то, как игра могла бы выглядеть с 3D перспективой(но, скорее всего, не будет):
Спасибо за внимание.
Показать полностью 2 1
1 год назад

Godot Engine. Библиотека новичка

Всем привет, дорогие товарищи! Как и было обещано, публикую подборку учебных материалов, которые помогли мне и моим товарищам освоить Godot Engine 🙂
В этом списке вы найдёте ссылки на материалы, которые можно охарактеризовать как Godot for beginners. Надеюсь, вам будет интересно 🙂
Если вы впервые слышите об этом движке, приглашаю ознакомиться с его описанием здесь:
Официальная Документация
Несмотря на то, что меня постоянно забрасывают какахами, когда речь заходит о доках, я продолжу настаивать на своём: УЧИТЕСЬ РАБОТАТЬ С ДОКУМЕНТАЦИЕЙ! Почему? — Никто лучше разработчика не знает, как устроен его продукт, так что к кому ещё обращаться, как ни к нему?
Godot Community не только постоянно улучшает и совершенствует движок, но также дописывает и детализирует официальную документацию. Здесь вы найдёте ответы на большинство вопросов, сталкиваясь с практическими проблемами. Да, вероятно, этой ссылке нечего делать в разделе «для новичков», но чем раньше вы освоите навык работы с доками, тем меньше набьёте шишек об углы движка (кстати, это касается любого программного продукта).
Между прочим, доки практически полностью переведены на русский язык.

Да, можно сколько угодно твердить, что по голым докам невозможно ничему научиться. Со своей стороны подчеркну, что если у меня возникает какая-то проблема, в первую очередь я лезу в доки, а потом уже на форумы, стэковерфло и т.д. В любом случае вы должны быть уведомлены, а том, что документация ведётся, она хорошо организована и удобна для использования 😉
В специальном раздели присутствует набор коротких туториалов, целью которых является ознакомление новичка с возможностями движка.
Подробный туториал о создании простой 2D игры
Серия очень простых уроков, где вас не будут грузить теорией, идеологией и архитектурой движка. Всё максимально просто: делай A, делай В, делай С — и вуаля полетел самолётик, заиграла музыка. Автор тутора предлагает нам сделать вместе с ним простую леталку-стрелялку. Уроки очень компактные, не требуют большой концентрации и много времени.
Прекрасный способ быстро и поверхностно познакомиться с движком и его интерфейсом, чтобы не только мозгами скрипеть несколько дней, но и удовольствие от результата получить 😉

Ссылка для скачивания ассетов указана в одном из первх уроков туториала.
Kids Can Code. Godot Recipes
Раздел, посвящённый Godot, в он-лайн школе Kids Can Code. Название школы говорит само за себя 😉 Здесь вы найдёте открытые мини-уроки, посвещённые решению практических задач.

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

Видео представляют из себя короткие уроки, посвещённые самым разным задачам — от проектирования и компановки интерыейса до обработки коллизий. Под многими видео вы также найдёте ссылки на официальные туториалы от разработчиков. Авторы канала с удовольствем общаются в комментариях, отвечают на вопросы.
Бонусом — пачка учебных материалов по визуальному редактору Krita.
YouTube канал пользователя под ником HeartBeast, где вы так же найдёте уроки по разработке простых коротких игр. У лектора прекрасная дикция, он довольно быстро говорит, но трудностей с пониманием, вроде бы, не возникает.

Материал несколько разрозненный, но здесь есть много интересного и познавательного 🙂 Новые видео выходят довольно регулярно.
Angega Studios
YouTube канал пользователя под ником Angega Studios. Сразу скажу, что у него не очень хороший английский и плохой звук, но зато он медленно говорит и разжёвывает каждую мелочь. Вместе с автором контента вы сможете создать три простенькие игры.
Под своими видео автор даёт ссылки на ассеты.

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

Канал живой. Администратор канала общается с пользователями в комментариях, отвечает на вопросы. Кстати, под каждым видео вы найдёте ссылку для скачивания используемых ассетов.
Game Endeavor
Личный блог одного из популяризаторов Godot. Канал специализируется на ретро-играх с пиксельной графикой. Строго говоря последнее обновление было год назад, но автор периодический проявляет активность в комментариях. Возможно, он просто нашёл работу и ему стало не до ютубчика :))

Автор контента не делает специальные уроки по изучению движка, но делится опытом по решению разных задач, показывает, как создавать и собирать ассеты, делится некоторыми трюками из личного опыта.
Сообщества и взаимопомощь
За 8 лет вокруг Godot Engine сформировалось очень дружелюбное и интересное сообщество. Люди с удовольствием помогают друг другу, отвечают на вопросы, делятся опытом разработки и игровыми ассетами.
Официальный форум вопрос-ответ. Форум, предназначен для взаимопомощи пользователей (иногда его посещают и разработчики движка). Цель форума проста: свести друг с другом вопрошающего и отвечающего.
На форуме действует система голосований за воспросы и ответы (примерно как на пикабу). Если вы встретили какой-то вопрос, он вам актуален, но всё ещё без ответа, тыкаете плюс — вопрос взлетает в рейтинге по актуальности. Просматривать сообщения пользователей без регистрации можно, закрытые разделы отсутствуют.
Godot на Reddit. Сообщество на Reddit — живое и дружелюбное. Несколько раз на Reddit мне отвечали гораздо быстрее, чем на форуме вопрос-ответ. Времнами складывается впечатление, что некоторые товарищи там сидят специально, чтобы помогать новичкам.
Сообщество Godot на Steam. Здесь люди, в основном делятся своими поделками и обсуждают популярные проблемы, связанные с разработкой на Godot. Оно не очень полезное, но позалипать на демки в порядке прокрастинации очень приятно и весело.
Разумеется, мне бы хотелось, чтобы наше сообщество на Пикабу тоже расширялось и наполнялось контентом, поэтому не стесняйтесь показывать свои наработки, делиться опытом, задавать вопросы. Надеюсь, что придёт время и Godot Engine станет полпулярным в России!
Небольшое напутствие всем, кто делает первые шаги в освоении движка
Я прекрасно понимаю, что изучать что-то новое и незнакомое очень трудно и временами дико бесит. Но если вы решили сделать свою собственную игру, дерзайте! Забейте на бурчание родных и друзей, что вы зря тратите своё время и «лучше бы занималисть [вставить нужное]».
Не бойтесь пробовать, делать что-то своё, творите и эксперементируйте! А чтобы немного поднять вам настроение и вдохновить на изучение движка, вот вам ссылка на демо потрясающего ретро-платформера, разработанного на Godot нашими дальневосточными друзьями:
Благодарю за внимание! Надесю вам было интересно! Если у вас остались какие-то вопросы, не стесняйтесь, спрашивайте в комментах. Если в моих силах будет помочь, я с удовольствием сделаю это 🙂
Всем хорошего вечера, успехов в изучении Godot и лёгкого старта в увлекательном игродельном мире! ^_^
P.S.: Годобот в заголовке нарисован мной. Картинка распространяется под Creative Commons Attribution 4.0 International License. Если вам нужна эта картинка, вы можете скачать её здесь:
В архив входят 4 картинки с вариациями фона и *.PSD файл.
UPD by @Boogernator: Полезным может ещё оказаться канал, ролики маленькие, про небольшие полезные мелочи рассказывают.
UPD by @captainperson: Еще для любопытных, Стим-куратор игр, сделанных на Godot. В основном любительские поделки на коленке, но уже имеются весьма успешные игры.
UPD by @MFSUS: тутор с которого я начал.
Показать полностью 9 1
Поддержать
1 год назад

[С нуля #0] Начало разработки новой игры в Godot Engine
Привет всем! Меня зовут Пётр.
Отвечу на уже задаваемый сотню раз вопрос: я знаю, что Godot — не самый популярный для мобильной разработки движок, но я выбрал его давно, активно изучал и разобрался со многими аспектами разработки.
![[С нуля #0] Начало разработки новой игры в Godot Engine Разработка, Gamedev, Мобильные игры, Инди, Инди игра, Видеоигра, Godot Engine, Альтернативная реальность, Видео, YouTube, Длиннопост](https://cs12.pikabu.ru/post_img/2022/09/18/7/1663500670132394565.jpg)
В Godot я сделал игру Бункер 21, которая в своё время добилась больших успехов. По моим меркам, конечно же.
Однако, время идет, ошибки копятся, и в жизни каждого разработчика когда-то наступает момент, когда разработка начинается заново. Будь то новая игра, новое приложение, или что-то ещё.
Я же начал разрабатывать с нуля ядро игры. В свою очередь старое ядро, которое я «полировал» и отлаживал для «Бункера», повертев, потестировав, решил, что, как бы я не старался раньше, кодовую базу требуется тщательно переосмыслить. С учётом нового опыта, с учётом всех «всплывших» нюансов, я принялся за работу. Пришлось попотеть.
![[С нуля #0] Начало разработки новой игры в Godot Engine Разработка, Gamedev, Мобильные игры, Инди, Инди игра, Видеоигра, Godot Engine, Альтернативная реальность, Видео, YouTube, Длиннопост](https://cs12.pikabu.ru/post_img/2022/09/17/12/1663445316171458697.jpg)
Несколько месяцев ушло на то, чтобы с нуля переписать весь требуемый функционал: систему AI, управление персонажем, систему окружения, систему обработки звуков, работу с камерой, физикой, ввод с сенсора, ввод с клавиатуры, и ещё кучу всего, что происходит «под капотом» игры.
К тому же, всё это должно корректно работать на телефонах, которые не могут похвастаться обилием памяти и процессорных мощностей.
![[С нуля #0] Начало разработки новой игры в Godot Engine Разработка, Gamedev, Мобильные игры, Инди, Инди игра, Видеоигра, Godot Engine, Альтернативная реальность, Видео, YouTube, Длиннопост](https://cs12.pikabu.ru/post_img/2022/09/17/12/1663445938171540020.jpg)
В какой-то момент я остановился. Работы была окончена. Ядро готово, а значит, наступило время создавать саму игру. Ещё месяц на моделирование уровней первой главы, параллельно писал сюжет и подбирал звуки.
В итоге на свет родился новый проект — игра «Альтернативный мир. Часть 1».
Игра рассказывает об одном персонаже из игры «Бункер 21», но с совсем другой стороны, нежели было показано в основной игре. Сразу же даются ответы на вопросы, касающиеся второстепенных персонажей и их способностей.
Я полностью переделал графическую часть, построение сцены и систему классов, отвечающих за эффекты и работу с трёхмерным миром, теперь звук реагирует на пространство, в помещениях слышимость окружающей среды снижается, зато звуки шагов и голоса становятся четче из-за меньшего рассеивания и смешивания с окружением.
Ну и да, игра не тормозит даже на самых слабых телефонах, отображая различные графические эффекты, например — огонь. Для особо тяжелых случаев можно включить пиксельную графику, это срезает область перерисовываемой части экрана, за счет снижения «разрешения» камеры.
![[С нуля #0] Начало разработки новой игры в Godot Engine Разработка, Gamedev, Мобильные игры, Инди, Инди игра, Видеоигра, Godot Engine, Альтернативная реальность, Видео, YouTube, Длиннопост](https://cs14.pikabu.ru/post_img/2022/09/18/7/1663498995158627144.jpg)
В конечном счете процесс разработки перешагнул точку невозврата, все аспекты работы учтены, благо прошлый опыт позволяет на него опираться для ускорения нынешнего.
Я завершил первую главу игры, и уже отправил её на рассмотрение в Google и Apple.
Посмотрим, что из этого выйдет.
Желать мне удачи не прошу, но очень надеюсь, что всё получится!
Ну и вот, небольшой собранный на коленке «трейлер».
Показать полностью 4 1
1 год назад

Публичный проект #4
Ремарка: Пост о том как я разрабатываю ремейк cdda
Начнем с того что я долго планировал это AI

Он конечно глуп в восприятии всегда держится возле стенки из за использование стандартного navigation server движка и я планирую реализовать свой
Как я его сделаю? Очень просто! стандартная навигация движка ставит точки где захочет но я сделаю иначе навигация будет задавать относительно центра тайловой сетки

Тоесть бот видит мир вот так и упрощает варианты выбора точек
Также боты реагируют на каждый звук вокруг них — стелс доступен
Следующее это транспорт теперь он имеет освещение
Также звук мотора и механику переключение скоростей

Также добавлен кеш для экономии ОЗУ
Следующее в планах
Вопрос для дискуссии:
Я прочитал основной лор Cataclysm: dark days ahead. Как думаете продолжить оригинальный лор, пересказать или альтернативная реальность?
Как по мне оригинал лора слишком перемешанный. Какие то Ми-го почему их так назвали?
Некоторые модельки и тайлы взяты из интернета
До следующих выходных!
Показать полностью 2
1 год назад

Похоже верха нашей страны взялись за игровую индустрию всерьёз и надолго

В Госдуме совсем недавно предложили создать собственный игровой движок. С инициативой выступил заместитель председателя комитета Госдумы по информационной политике, информационным технологиям и связи Антон Горелкин.
Товарищ депутат выразил опасения о судьбе Atomic Heart, игры от московской студии Mundfish. Он верит, что проект выстрелит и будет качественным, но напомнил, что игра разрабатывается на Unreal Engine.
«Atomic Heart разрабатывается на игровом движке Unreal Engine, который принадлежит американской компании Epic Games. В начале марта она присоединилась к санкциям против России и прекратила продажу своих игр. Доступ к движку для российских разработчиков пока сохраняется, но в любой момент может быть прекращен. Та же история с другим стандартом игровой индустрии – движком Unity, который также принадлежит американцам», — подчеркнул Горелкин.
Он признал, что конкурентоспособных аналогов у России пока нет. Поэтому в сложившейся ситуации в России нужно в срочном порядке создавать свой игровой движок.
«Это должно быть open-source решение, которое российский геймдев сможет бесплатно использовать для своих проектов. Считаю это приоритетной задачей в части государственной поддержки отечественного игрового рынка, поэтому направил в Минцифры РФ предложение обсудить с отраслью эту идею и механизмы её скорейшей реализации», — написал Горелкин.
И вы знаете, всё это вызывает достаточно спорные чувства. С одной стороны, инициатива благая во всех смыслах. И людям в сфере IT будет чем заняться, у них будет бесценный опыт разработки движка с нуля, подготовки инструментария к нему. Для инди-разработчиков это тоже плюс, ибо имея стандартизированную платформу проще подходить к самой разработке, так как все будут понимать, как на ней работать.
С другой же стороны, всё упирается в несколько моментов. Первый и самый очевидный — а будут ли реально разрабатывать этот движок? Или его концепт будут переосмыслять раз 15, осваивая бюджетные средства. Вторым моментом, естественно, является качество итоговой продукции. Люди в крупных студиях не просто так отказываются от внутренних движков в пользу Unreal Engine 5. Вот возьмите CD Project Red даже. Это действительно крутой, навороченный и универсальный движок, на котором можно делать почти что угодно. Смогут ли наши родить что-то хотя бы уровня Unity — я не знаю, но последить за этим будет любопытно.
Подписывайтесь на наш блог, чтобы не пропустить новые интересные посты!
Godot (игровой движок) — Godot (game engine)
Godot — это двухмерный и трехмерный, кроссплатформенный, бесплатный игровой движок с открытым исходным кодом, выпущенный по лицензии MIT. Первоначально он был разработан Хуаном Линецким и Ариэлем Манзуром для нескольких компаний в Латинской Америке до его публичного выпуска. Среда разработки работает в нескольких операционных системах, включая Linux, macOS и Windows. Godot может создавать игры для PC, мобильных и веб платформ.
- 1 Обзор
- 1.1 Сценарии
- 1.2 Рендеринг
- 1.3 Другие функции
Обзор
Godot стремится предложить полностью интегрированную среду разработки игр. Он позволяет разработчикам создавать игры с нуля, не нуждаясь в других инструментах, кроме тех, которые используются для создания контента (художественные ресурсы, музыка и т. Д.). Архитектура движка построена на концепции дерева «узлов». Узлы организованы внутри «сцен», которые представляют собой группы узлов многократного использования, создания экземпляров, наследуемые и вложенные. Все игровые ресурсы, включая сценарии и графические ресурсы, сохраняются как часть компьютерной файловой системы (а не в базе данных ). Это решение для хранения данных предназначено для облегчения сотрудничества между командами разработчиков игр, использующими системы контроля версий программного обеспечения.
. Движок поддерживает развертывание на нескольких платформах и позволяет определять параметры сжатия текстур и разрешения для каждой платформы. В настоящее время поддерживаемые платформы включают Linux, macOS, Windows, BSD, Android, iOS, UWP, HTML5 и WebAssembly.
Скрипты
Игры с использованием Godot могут быть созданы с помощью различных языков программирования, включая C ++, C# и любой другой язык с привязками GDNative, например Rust, Nim и D.
Godot, также имеет собственный встроенный язык сценариев , GDScript, высокоуровневый, динамически типизированный язык программирования, очень похожий на Python. В отличие от Python, GDScript имеет строгую типизацию переменных и оптимизирован для архитектуры Godot на основе сцен. Разработчики Godot заявили, что многие альтернативные сторонние языки сценариев, такие как Lua, Python и Squirrel, были протестированы, прежде чем было решено, что использование специального языка позволяет оптимизация и интеграция редактора. Движок также поддерживает визуальное кодирование через собственный встроенный язык визуального программирования VisualScript, разработанный как визуальный эквивалент GDScript
Godot включает редактор сценариев с автоматическим отступом, подсветка синтаксиса и завершение кода. Он также имеет отладчик с возможностью установки точек останова и программных шагов.
Визуализация
Графический движок Godot использует OpenGL ES 3.0 для всех поддерживаемых платформ; в противном случае используется OpenGL ES 2.0. В будущем разрабатывается поддержка Vulkan. Движок поддерживает отображение нормалей, зеркальность, динамические тени с использованием карт теней, запеченные и динамические Global Illumination и полноэкранные пост- эффекты обработки, такие как bloom, DOF, HDR и гамма-коррекция. Также включен упрощенный язык шейдеров, аналогичный GLSL. Шейдеры можно использовать для материалов и постобработки. В качестве альтернативы их можно создавать, манипулируя узлами в визуальном редакторе.
Godot также включает в себя отдельный графический движок 2D, который может работать независимо от 3D-движка. Двумерный движок поддерживает такие функции, как освещение, тени, шейдеры, наборы тайлов, параллаксная прокрутка, полигоны, анимация, физика и частицы. Также возможно смешивать 2D и 3D с помощью «узла просмотра».
Другие функции
Godot содержит систему анимации с GUI для скелетной анимации, наложения, деревья анимации, морфинг и кат-сцены в реальном времени. Практически любую переменную, определенную или созданную в игровом объекте, можно анимировать. Движок использует Bullet для моделирования трехмерной физики.
Дополнительные функции включают:
- графики анализа производительности
- запекание света
- многопоточность
- система плагинов
- цели рендеринга
- Воспроизведение видео с использованием кодека Theora
- Воспроизведение звука кодеков Ogg Vorbis и WAV
- Система частиц
- Текстура конвейер импорта / экспорта / сжатия
- Поддержка Navmesh
- Графический интерфейс пользователя
- Клавиатура, мышь, геймпад и сенсорный экран поддержка
История
Развитие Годо было начато Хуаном ‘Редузом Линецким и Ариэлем’ punto ‘Манзуром в 2007 году. Линецкий заявил в презентации, что имя «Годо» было выбрано из-за его связи с Игра Сэмюэля Беккета В ожидании Годо, поскольку она представляет бесконечное желание добавить новые функции в движок, которые приблизили бы его к исчерпывающему продукту, но никогда не сделают этого. В феврале 2014 г. исходный код для Godot был опубликован на GitHub по лицензии MIT.
15 декабря 2014 г. Godot достиг версии 1.0, что означает первый стабильный выпуск и добавление lightmapping, поддержка navmesh и другие шейдеры. Версия 1.1 была выпущена 21 мая 2015 года, добавив улучшенное автозаполнение в редакторе кода, редактор визуальных шейдеров, новый API в операционную систему для управления экранами и окнами, переписанный 2D-движок, поддержка нового 2D-навигационного многоугольника, значительно улучшенный экспортер Blender Collada и новая темная тема. Новый на тот момент 2D-движок включал шейдеры, материалы, независимое Z-упорядочение для каждого узла, источники света, тени с многоугольными окклюдерами, отображение нормалей и поддержку шрифтов с дистанционным полем. Годо присоединился к Software Freedom Conservancy 4 ноября 2015 года.
Godot 2.0 был выпущен 23 февраля 2016 года. Новые функции включали улучшенное создание экземпляров и наследование сцен, новый браузер файловой системы, редактирование нескольких сцен и усовершенствованный отладчик. За этим последовала версия 2.1 в августе 2016 года, в которой были представлены база данных активов, профилировщик и API плагинов.
22 июня 2016 года Godot получил 20 000 долларов США Mozilla Open Source Support (MOSS) Награда «Партнеры миссии» будет использована для добавления поддержки WebSockets, WebAssembly и WebGL 2.0. Позже, при поддержке Мигеля де Икасы, Годо получил пожертвование в размере 24000 долларов от Microsoft на внедрение C # в качестве языка сценариев в Godot.
Версия 3.0 была выпущена 29 января 2018 года, добавив совершенно новый рендерер PBR реализовано в OpenGL ES 3.0, совместимость с виртуальной реальностью и поддержка C # (через Mono ). Версия 3.0 также добавила физический движок Bullet в дополнение к встроенной в него 3D-физике и стала первой версией Godot, включенной в Debian. Godot 3.1 был выпущен 13 марта 2019 года, наиболее заметными особенностями которого являются добавление статически типизированного GDScript, системы классов скриптов для GDScript и модуля рендеринга OpenGL ES 2.0 для старых устройств и мобильных устройств. Godot 3.2 был выпущен 29 января 2020 года, наиболее заметными особенностями которого являются значительные улучшения документации, значительно улучшенная поддержка C # и поддержка файлов glTF 2.0. Ведущий разработчик Хуан Линецкий большую часть времени работал над отдельной веткой Vulkan, которая позже будет объединена в master для 4.0, поэтому работа над 3.2 в основном выполнялась другими участниками. Работа над 3.2 продолжается в виде выпуска с долгосрочной поддержкой, включая Godot 3.2.2 от 26 июня 2020 года, большой выпуск исправлений, в который добавлены такие функции, как OpenGL ES 2.0 пакетная обработка и поддержка C # для iOS.
3 февраля 2020 года Godot получила награду Epic Games в размере 250 000 долларов США за улучшение графического рендеринга и встроенного в движок языка разработки игр GDScript. 8 июля 2020 года Хуан Линецкий упомянул, что награда Epic Games будет использована для постоянного найма себя и Джорджа (Маркеса) на 2 года с целью бесплатного пожертвования средств для новых целей.
Использование
Многие игры OKAM Studio были созданы с использованием Godot, в том числе Dog Mendonça и Pizza Boy, в которых используется расширение для приключенческих игр Escoria. Кроме того, он был использован в программе средней школы Западной Вирджинии из-за простоты использования для непрограммистов и того, что описывается как «множество учебных материалов, которые уже существуют для программного обеспечения. «.
См. Также
- Портал видеоигр
- Список игровых движков
- Разработка видеоигр
Ссылки
Внешние ссылки
- Официальный сайт
- godot на GitHub