tgindex
XashNT

XashNT: Блог Разработчика Прямая связь: @XashAdmin_bot

Последний пост
9 авг.
Последнее чтение
13:31
Постов за неделю
0
Всего постов
20
Тип
открытый
Язык
русский
Категория
Технологии
В каталоге с
13 авг.
Подписчики
451
−1 за 4 дн.
Сутки
0
0,00%
Неделя
 
Месяц
 
Просмотров на пост
454
20 постов
Вовлечённость
100,7%
к подписчикам
Постов в день
0,0
всего 20
Упоминаний
0
каналов
Охват размещения
оценка
1/24сутки в ленте
228
1/48двое суток
261
1/72трое суток
281

Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.

Посты

  • 9 авг.263128

    https://store.steampowered.com/app/3709990/Tale_of_the_Bullet_Knight/

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • без подписи

  • 9 авг.238114

    Независимый проект наших друзей: The tale of Bullet Knight выходит в ранний доступ 10-го августа! У нас ретро-шутер с упором в роуглайт с непрощающими врагами и командой до четырех игроков! Графика нарисована отчасти вручную, свыше 1500 изображений создано только для раннего доступа и 12 врагов, 13 деталей для оружие и 4 билда ждут вас!

  • 31 июл.4882613

    Привет! 18, 19 и 20 сентября в Сколково будет проходить выставка-фестиваль видеоигр Игропром. Мы - Дядя Миша и Дикс - будем там. Хотите встретиться - пишите заранее, например, в комменты к этому посту, договоримся! Будем рады познакомиться с каждым.

  • 30 июл.412117из nemyax

    Видос с перетекстуром

  • В игре In a Bind, которая разрабатывается под XashNT, её автор, nemyax применил интересный способ процедурной генерации текстурных координат. Результат вы можете наблюдать на видео. От себя добавлю, что бесшовное текстурирование отлично сочетается с Parallax Occlusion Mapping

  • Самым простым и проблемным решением было бы просто взять любой известный оконный менеджер и начать писать редактор на нём. Простым - потому что первые результаты были бы получены довольно скоро, проблемным, потому что практически все подобные менеджеры на данный момент представляют собой гигантские эко-системы со своей логикой и идеологией. И кстати сказать, ваш любимый imGui, который когда-то завоевал популярность как раз за свой малый вес и простоту в использовании, начинает их стремительно догонять. Не знаю, поднималась ли эта тема в IT-пространстве или я первый, кому эта мысль пришла в голову, но компоненты программных продуктов имеют собственную гравитацию. И чем продукт масштабнее - тем сильнее он оказывает влияние на ваш собственный проект, в котором вы его используете. Сначала вы берёте что-то "для ускорения разработки", но чем сильнее разрастается ваш собственный проект, тем сильнее начинает проявляться несовпадение идеологий вашего проекта и тех библиотек, которые вы используете. И из этой ситуации всего два выхода - либо отказ от выбранных библиотек в пользу других (что далеко не всегда возможно), либо следование в навязанной идеологии выбранных вами компонентов. Тут следует учитывать ещё тот факт, что у продуктов с давней историей часть поведения может быть обусловлена не изначальной идеологией, а просто историческими решениями\чьими-то реквестами, которые были актуальны, например, в нулевые годы, а сейчас могут только мешать. Причём причудливая смесь легаси может сочетаться со сменой бинарной совместимости, о которой я упоминал в предыдущем посте. Конечно всё преодолимо, но, повторюсь, играть в эти догонялки и зависеть от сторонних компонентов, особенно в наше время, мне совершенно не хотелось. Тем более что была возможность этого избежать. Собственно такое длинное вступление было сделано, чтобы помочь прояснить ситуацию, почему на канале так долго не было никаких постов. Готовился полноценный бакэнд для разработки. Дело это скучное, картинками его не проиллюстрируешь, рассказывать о подобных вещах людям, которые выбирают сторонние библиотеки, как раз, чтобы обо всём этом не думать - наверное не самая лучшая идея. Но тем не менее, если кому-то было интересно, надеюсь, я ответил на их вопросы. Ну а теперь, наконец-то можно переходить к конкретике и вместо скучных вопросов - через что лучше рисовать окна и контролы, сосредоточиться на обсуждении раскладки 3D-окон редактора, менеджера объектов, эксплорера материалов, ресурсов, машины времени (Undo\Redo) и основным концепциям в редактировании, с учётом новых веяний. Об архитектуре будущего редактора скоро выйдет большой пост, не переключайтесь.

  • Ну что ж, товарищи, вся низкоуровневая работа по подготовке XashNT к разработке редактора наконец-то завершена. И от абстракции наконец-то можно переходить к конкретике, а именно - к разработке редактора уровней. У подписчиков разумеется могут возникнуть вопросы - что можно было делать столько времени, ведь редактор анонсировался чуть ли не каждый год, и каждый раз переносился. Поясню. Анонсы были, но по факту каждый раз в приоритете оказывались какие-то другие задачи, а поскольку совсем уж без редактора движок не оставался (был, как вы помните кастомный билд JackHammer и набор плагинов к Blender), то и сроки всё время сдвигались. Фактически подготовительные работы начались только в феврале этого года. Напоминаю, что был представлен универсальный просмотровщик ресурсов, полностью написанный на Shot. Тогда же родилась и уточнённая концепция "двух ядер", когда одно ядро игрового движка - классическая клиент-серверная модель, а второе ядро - абстрактное приложение с обычной точкой входа main, но пишется оно полностью на языке Shot, позволяя использовать WinAPI, как если бы вы писали приложение на нативном C++. Вопреки опасениям, это не сказалось на производительности, поскольку основные тяжёлые операции выполняются непосредственно в ядре, а на Шоте написана только бизнес-логика. Если вы хотите сравнения, для понимания, то можно привести в пример платформу Qt. Фактически у меня получилось то же самое, но конечно же с рядом оговорок: Qt разрабатывается с 95-го года, он всегда делал упор исключительно на интерфейсы и в нём нет полноценного скриптового языка (насколько я знаю какой-то есть, но весьма примитивный и ограниченный), в противовес этому ядро для разработки приложений XashNT изначально получило наследие в виде оптимизированного 3D-рендерера с мощной системой материалов и гибкими настройками, полноценный скриптовый язык для разработки и абстрактный слой обращения к WinAPI. Насчёт WinAPI стоит так же сказать пару слов - на данный момент по сути это единственное стабильное API для отрисовки интерфейсов и взаимодействия с ними. Логичнее поддерживать совместимость именно с ним, держа в уме наличие различных эмуляторов платформ, типа WINE, где это взаимодействие гарантированно никто не сломает, в отличие любых других библиотек оконных менеджеров, которые, то никто не обновляет годами, то вдруг переписывают на Rust, то полностью меняют API. Может быть кому-то нравится подобная суета, но я в их число точно не вхожу. В конце-концов, даже Торвальдс не так давно выступил с заявлением, мол прекратите ломать пользовательское пространство, но сложно сказать был ли он услышан, правильно ли его поняли и через сколько лет начнут реагировать. Следовательно мы пойдем другим путём. Возможно этот путь не слишком популярен в настоящее время, но оценить правильность подхода сразу возможным не представляется, а следовать за широкими народными массами только потому что "сегодня все делают именно так" мне никогда не нравилось.

  • 2 июл.557172

    Один из завершающих штрихов разработки языка Shot - теперь в его бинарный образ можно встраивать произвольные ресурсы, как и в обычные нативные приложения. Соответственно в компилятор языка добавился встроенный компилятор ресурсов. Но есть и важные отличия. Обычно встраивание ресурсов не регламентируется какими-либо спецификациями, каждый реализует это по-своему и, как правило, в силу сложившихся исторических причин. У MSVC это файл .res и численные идентификаторы ресурсов, хотя WinAPI предоставляет возможность поиска ресурса по его имени. В Shot устроено немного иначе - ресурсы подключаются в исходных файлах при помощи директивы #resource. После того как проект успешно скомпилирован и слинкован - запускается компилятор ресурсов и вот здесь есть важное отличие. Компилятор грузит только что собранный образ программы и ищет в нём специально определённую функцию с названием _include_resource. Если её нет, то встраивает ресурсы согласно внутренней спецификации, которая на данный момент образует иерархию, похожую на таковую в нативных Win32 приложениях. То есть специальная подпапка с номером соответствующим принятому идентификатору языка и дальше идёт набор жестко определённых имён папок, соответствующих принятым в WinAPI константам, таким как RT_ICON, RT_BITMAP, RT_FONT и аналогичным. Это сделано ради совместимости с WinAPI и для того, чтобы проброшенные в язык функции загрузки ресурсов могли прозрачно работать как с системными библиотеками, так и с исполняемым файлом самого Shot. Если же компилятор находит функцию _include_resource внутри только что скомпилированного образа, то запускает его на выполнение в особом режиме, в частности cinit\cexit не вызываются, только сама функция _include_resource, на вход которой подается имя этого ресурса. В распоряжении программиста есть также особая импортируемая функция WriteResource, которая добавляет ресурс в исполняемый файл. Причём вы можете указать не только имя, но и буфер в памяти для добавления. Такой подход открывает возможность максимально гибкого управления ресурсами - вы можете конвертировать загруженный ресурс из текстового в бинарный и добавлять в образ именно его, можете на лету сжимать изображения, например из bmp в png, можете в качестве ресурса использовать текстовый список с перечислением ресурсов и добавлять их в цикле за один вызов _include_resource. То есть полностью на усмотрение программиста. Теперь в языке достаточно инструментов для разработки игрового редактора. В сущности разработка всё это время велась параллельно, но ещё не достигла того состояния, когда об этом есть что написать на канале, поэтому новостей и не было. Надеюсь уже в конце этого месяца показать вам концепцию будущего редактора и основные задумки по реализации UI\UX.

  • Напишите, пожалуйста, в комментариях, какие направления разработки движка вы хотели бы изучить? Какие 2-3 темы интересуют вас больше всего?

  • 4 июн.785218

    без подписи

  • 18 мая970168

    https://www.youtube.com/watch?v=TyD48EksgNI Xash3D портировали на Nintendo 64

  • 16 мая796131

    Теперь к главному вопросу - ради чего это всё понадобилось? Как вам известно и Си и C++ относятся к семейству языков, которые крайне плохо подходят для написания оконных интерфейсов. Си для этого не годится вообще, C++ ограниченно годен, но с кучей костылей, например в виде стороних или встроенных генераторов мета-информации, которые решают лишь малую часть проблем при написании оконного менеджера. Возможно ситуация получит тенденцию к улучшению после выхода нового стандарта C++26 (или может он уже вышел, честно говоря, не следил за датами). Но повторюсь, в любом случае, встроенная рефлексия в новом стандарте решит лишь малую часть проблем, которые в Delphi были решены из коробки более 30 лет назад. Различные скриптовые языки имеют неплохие возможности для написания оконных менеджеров (например C# или Java), однако они зачастую являются частью самого языка без возможности кастомной реализации. Shot, напоминаю, идеологический наследник C++. Следовательно он автоматически унаследовал и все проблемы, касающися реализации оконных менеджеров на этом языке. Смысла в языке, который похож на C++, имеет все те же проблемы, но при этом значительно медленнее его, в силу не нативного выполнения, а интерпретатора байт-кода, как вы понимаете не слишком много. Язык должен был не просто получить новые возможности, которых никогда не было в C++, но выдержать проверку на практике, на натурном эксперименте. Портирование VCL в этом смысле мне показалось наиболее оптимальным стресс-тестом для языка. Уж если подобная концепция сможет корректно работать на Shot, значит тут вообще не будет никаких ограничений в плане создания интерфейсов. И что немаловажно - тестовый порт VCL полностью написан на Shot, он имеет никакой поддержки в бакэнде. За исключением самых общих механизмов, которые можно использовать любых сценариях по вашему усмотрению. Т.е. Shot это скриптовой язык, на котором можно написать фактически любой оконный менеджер без той боли, которая бы неизбежно сопутствовала разработке аналогичного проекта на C++. Что дальше? VCL в чистом виде использоваться не будет. Мы рассмотрим вопрос о легальности подобного использования, но в сущности это не так уж и важно. С подобными возможностями языка можно создать куда более удобный и продвинутый оконный менеджер, нежели VCL, активно используя вышеупомянутые конструкции языка, которые в самом Shot реализованы на более расширенном уровне и могут применяться в любых сценариях, в отличие от Delphi. Разумеется и внутри-игровые меню с рендерингом в 3D окна тоже могут быть созданы с использованием этих механизмов, а наши бета-тестеры (наиболее любопытные из них), наверняка отметили активное применение и virtual_new и dynamic_call в игровом коде рендеринга HUD и меню. Ну а если ещё нет, то вот вам прекрасный повод полюбопытствовать. Большинство вышеупомянутых механизмов существуют в языке ещё с 22-го года, однако полноценный стресс-тест они смогли пройти только сегодня. С чем я нас всех и поздравляю! Ура, товарищи!

  • 16 мая441101

    4. Кастомные WndProc. Не являются частью языка, скорее чем-то вроде хака. Суть в том, что для каждого окна генерится уникальный каллбэк, который превращает типичный набор аргументов WndProc в структуру - для удобства. Так же эти структуры могут динамически подменяться в рантайме, по принципу объединений. Поэтому в разные функции с dynamic id приходит ссылка на идентичную по размеру, но разную по содержанию структуру - в зависимости от контекста вызова. Это нельзя назвать полноценным полиморфизмом конечно, скорее узкоспециализированным решением, персонально для VCL. Тем не менее механизм хорошо работает. 5. Рефлексия для перечислителей (enum). Насколько мне известно данная фича должна появиться в стандарте C++26, а в Delphi она была изначально. Это позволяет сохранять константы как имена и загружать их обратно. Разумеется без какой-либо ручной работы (хотя в VCL есть оба подхода, часть таких констант оформлена в пользовательские таблицы, часть берётся из RTTI автоматически), 6. Модульность, с возможностью инициализации-деинициализации модулей, при загрузке\выгрузке приложения. В C++ это можно было бы решить через гигантский класс-сигнлтон на каждый файл, но это крайне неудобно. А для неймспейсов не существует способа вызова тех или иных функций в cinit\cexit, это делается только для конструкторов\деструкторов глобальныъ объектов. В Shot подобное реализуется через директиву препроцессора. 7. Пост-конструкторы и пре-деструкторы. Вызываются соответственно после того как объект полностью сконструирован и исключение не было выброшено, пре-деструктор соответствено - перед вызовом деструктора. В VCL являются тоже важной частью логики. В Shot реализованы аналогично через директиву препроцессора с возможностью сделать данные методы виртуальными, а так же иметь их неограниченное кол-во на объект. 8. Ключевое слово finally в исключениях. В C++ его попросту нет, VCL весь по сути построен на его использовании. Shot в исключениях поддерживает и catch и finally, причём поведение исключений реализовано как в C++ - т.е. с автоматическим вызовом деструкторов (и вышеупомянутых предеструкторов) локальных объектов. 9. Пожалуй одна из самых важных фичей Delphi - виртуальные конструкторы. Тип объекта можно сохранить в переменную, а потом динамически создать новый объект, используя содержимое переменной в качестве шаблона. Ничего подобного в C++ реализовать невозможно. Даже на шаблонах. А это активно используется, причём тип объекта может меняться в рантайме. В Shot есть специальный оператор virtual_new, позволяющий создавать полноценный объект, используя в качестве описания содержимое из обычной строки (то есть тип класса, сохранённый в строку). Этот пост был написан не с целью критики C++, в Delphi, к сожалению тоже хватает своих ограничений, о которых я пожалуй не буду распространяться, в силу поверхностного знакомства с этим языком, а для того чтобы познакомить вас с возможностями языка Shot, ну а программисты примерно могли оценить масштаб проделанной работы. Потому что скриншот окошка, представленный в предыдущем посте никоим образом не даёт повода думать, насколько же это было непросто и сколько различных технических проблем пришлось в итоге разрешить.

  • Delphi - удивительный язык. С одной стороны по возможностям он сильно уступает C++ (хотя многое и подтянули в последних версиях), с другой там есть вещи, которых в C++ не было никогда, и вероятно никогда и не будет. Именно из-за наличия в языке этих конструкций VCL становится фактически непортабельной вещью в себе. Даже сами авторы Delphi, создавая C++ Builder пустились на хитрость. Не могу в точности сказать как это было устроено, может в процессе участвовало два компилятора, может быть их реализация C++ так же умела работать и с Delphi, но факт остаётся фактом: C++ Builder использует тот же самый VCL написанный на Delphi. Давайте поговорим о том, какие же фичи Delphi, делают его использование практически непортабельным. 1. Свойства. На первый взгляд это довольно простая фича, которая может поддерживаться компиляторами C++ в качестве расширения. Однако в Delphi свойства сохраняют область видимости даже после компиляции проекта в бинарный файл. К тому же с ними можно взаимодействовать с помощью абстрактного интерфейса - выполнять поиск свойства по имени и считывать\задавать значение при помощи двух низукоуровневых функций: GetPropValue и SetPropValue. Воспроизвести подобное в C++ можно только вручную или помощью генераторов мета-даты, что крайне неудобно. Собственно Qt именно этим и занимается - перед компиляцией генерируются свойства оконных классов. В Shot, полноценно поддерживаются свойства как в Delphi, но есть и важные отличия - возможность создавать виртуальные свойства. В VCL это не используется, но как фича для языка имеет применение. 2. Динамические методы, dynamic_call. Конкретно в Delphi это скорее хак, позволяющий выполнять поиск по строго определённому набору функций из единственного места и единственного класса. За это отвечает функция GetDynaMethod, написанная на ассемблере. То есть строго говоря это не совсем часть языка, а однако номера функций задаются именно при их декларации. В C++, как вы знаете номер функции тоже можно задать, но он всегда будет равен нулю и это означает абстрактную виртуальную функцию, т.е. интерфейс. Ну а в Delphi мы можем задавать произвольный номер в 16-битном диапазоне. Эту фичу на C++ реализовать тоже крайне проблематично, придётся опять же создавать для каждого класса гигантский ассоциативный массив с парами - dynamic ID - указатель на класс функции. Напоминаю, что смысл языка как раз в том, чтобы освобождать программиста от дурной, рутинной работы. В Shot dynamic_call - полноценная часть языка, позволяющая вызывать методы внутри объектов, внутри неймспейсов, в глобальном пространстве и делать это с произвольным кол-вом аргументов (дедуктор перегрузки работает прямо в рантайме). 3. Указатели на методы. В C++ эти указатели по непонятным причинам имеют весьма строгую типизацию, чтобы исключить даже малейшую возможность неверного вызова. Любое несовпадение базового типа требует вызова static_cast для приведения типов. К тому же указатель на объект, метод которого хранится в указателе программист должен как-то таскать отдельно. Это в конечном итоге привело к тому что указатели на методы в C++ не жалуют и стараются не использовать. В Delphi эти указатели устроены совершенно иначе. Они состоят из пары "метод-указатель на класс" что позволяет считать подобную структуру самостоятельной единицей и вызывать из любого места, при условии что он был правильно проинициализирован. Конечно подобный подход может быть опасен, например при обращении к методу, объект которого уже был удалён, однако непосредственно для Shot, это проблемой не является, здесь есть способы валидации уже освобожденных объектов. Реализация вышеописанных указателей на метод в Shot является пользовательской и шаблонной, однако на уровне языка поддерживается особый тип конструктора, который позволяет за один вызов проинициализировать весь класс.

  • 16 мая496173

    Те, кто внимательно следил за сообщениями на канале наверное уже догадались в чём дело, а для остальных сообщаю: мне действительно удалось портировать Visual Components Library с Delphi на собственный язык Shot. Скорее всего, это первый и единственный в мире случай, портирования данной библиотеки на C++ подобный язык, если не считать C# который был создан Андресом Хейлсбергом, автором Delphi и VCL, которого Microsoft в начале нулевых переманила к себе, как раз для разработки нового языка. И который во многом унаследовал идеологию Delphi в плане композиции окон. Но C# это всё же отдельный язык, несовместимый с C++, к тому же в его создании участвовал сам автор Delphi. Так что можно с полным правом сказать - действительно первый случай. Немного позже подробно расскажу о возможностях языка Delphi, и о том, почему прямой порт VCL на C++ так до сих пор никто и не осуществил. И почему это удалось только на собственном языке, который получил множество важных фишек из Delphi, не в последнюю очередь с прицелом на будущий порт VCL. И вот наконец это свершилось. PS. Даже для создания такого простого окна VCL исполняет примерно пару миллионов инструкций.