В новой версии Dagon будет встроенный звуковой движок на основе SoLoud — расширение dagon:audio. Поясню для тех, кто не знает: SoLoud — это библиотека-микшер с поддержкой 3D-звука и базовых потоковых форматов (WAV, MP3, OGG, FLAC), а также трекерных форматов через OpenMPT. Есть частотные фильтры и встроенные синтезаторы — в частности, текстово-речевой преобразователь, SFXR, эмулятор VIC-20 и генератор разных видов шума. SoLoud поддерживает множество бэкендов, и по дефолту работает на основе SDL2, как и сам Dagon (пользователь, однако, может выбрать конкретный бэкенд через опцию audio.backend в settings.conf). Короче говоря, это своего рода «FMOD от мира OpenSource». Особо отмечу удобный API и, более того, прямо из коробки — обертка для D, позволяющая писать в объектно-ориентированном стиле.
Статьи автора: Gecko
GScript3
В D все очень плохо со встраиваемыми скриптовыми языками. Перепробовал много вариантов — Lua, Python, AngelScript — везде боль, все делается через неимоверно сложный API, где элементарно привязать к скрипту свою функцию — это целый квест. Чтобы, например, использовать биндинг dangel, нужно патчить рантайм языка для поддержки соглашения вызовов функций D, без этого там ничего не будет работать. Под Lua-биндинги очень сложно найти нужную версию библиотеки, чтобы приложение не крашилось. Pyd, привязка Python — вообще какой-то фантастически запутанный фреймворк из compile-time костылей, к которому нет никакой документации, даже в виде комментов в коде. Нативные языки, написанные на D, по большей части устаревшие, неподдерживаемые и тупо не компилируются.
Поэтому я уже много лет назад начал пилить свой язык GScript. Изначально это был больше учебный проект, у меня все не хватало времени довести до ума виртуальную машину — первые два варианта GScript являются просто прототипами. Третья итерация, кажется, приобретает уже законченный вид.
(далее…)Programmer’s Notepad Reloaded
Некоторые, я думаю, знают, как я люблю старый/экзотический софт) Например, я до сих пор использую редактор Programmer’s Notepad, заброшенный еще с 2016 года. Ну а что, вещь хорошая, проверенная, редактор не перегруженный, не тормозит, не мешает подсказками. Поддерживает D из коробки. Конечно, это не IDE, но лучший «продвинутый блокнот» из бесплатных. На днях решил сделать его форк под названием Programmer’s Notepad Reloaded: https://github.com/gecko0307/pn-reloaded. Пока ничего значительно не менял, только исправил мелкие проблемы совместимости с современной Студией и добавил схемы подсветки синтаксиса для GLSL и WGSL.
Для компиляции нужен Boost 1.57 (🤮) — его надо скопировать в lib/boost/boost-1_57_0. WTL скачивать не нужно, я его положил прямо в репозиторий, так как весит совсем мало.
Можно скачать готовую сборку на странице релиза. К сожалению, пока только x86 — в 64-битном режиме PN собрать затруднительно из-за старых библиотек, но я работаю над этим.
Ретроспектива: Bud, DSSS и другие старые системы сборки
До появления DUB в 2012 году в сообществе D-шников не было единой системы автоматизации сборки. Все использовали что-то свое — от классического Make до кастомных скриптов. Расскажу о нескольких таких проектах, которые застал лично.
Build/Bud
Согласно deadalnix, первой известной системой сборки для D была программа Build (впоследствии переименованная в Bud), которую написал Дерек Парнелл в середине нулевых. Является ли название DUB отсылкой к этому проекту, я точно сказать не могу, но вероятность такая есть) В 2011 году Bud 3 была портирована на D2, ее даже можно скачать по ссылке ниже.
Как и все ранние системы сборки, Bud использовала собственный формат конфигов, похожий на INI-файлы. Конфигурация в нем была до крайности громоздкой и неудобной, и альтернативы стали появляться, как грибы после дождя.
Страница Build/Bud на DSource: https://dsource.org/projects/build
D Shared Software System (DSSS)
Довольно мощная система сборки, написанная Грегором Ричардсом в качестве альтернативы Build. DSSS, строго говоря, был комплектом из сборщика Rebuild и пакетного менеджера DSSS. Для конфигурации он использовал файлы *.conf, концептуально тоже близкие к INI — наборы пар «ключ=значение». Интересной фичей DSSS была поддержка нескольких таргетов в одном конфиге: конфиг мог быть поделен на секции, каждая из которых описывала сборку отдельного таргета, ассоциированного с указанным главным модулем:
[example.d]
target=example_binary
Можно было собирать один и тот же модуль в разных конфигурациях:
[example.d+withfeature]
target=example_binary_withfeature
buildflags=-version=withfeature
Также поддерживались хуки (prebuild, postbuild, preinstall, postinstall и др.), которые впоследствии были реализованы и в DUB. Другая концепция родом из DSSS — возможность установки собранного ПО в систему, аналогично dub fetch/dub run.
DSSS был написан на D1, поэтому я его не использовал — на D1 я никогда не писал, сразу начал с D2, и было жутко неудобно ставить обе версии языка сразу. Позже появился проект по портированию DSSS на D2, но я с какого-то момента перестал за ним следить.
Страница оригинального DSSS на DSource: https://dsource.org/projects/dsss
Форк для D2 на GitHub: https://github.com/apriori/dsss
xfBuild
Тоже проект родом из нулевых, система сборки от легендарного h3r3tic. Одно время была перспективной альтернативой DSSS, но, к сожалению, тоже исключительно под D1, да еще под Tango — поэтому подробно о ней ничего сказать не могу, я ей никогда не пользовался.
Существует порт xfBuild на D2: https://github.com/SiegeLord/xfbuild
Cook
Был период в истории D, когда все пользователи поделились на два лагеря — сторонники Bud и любители DSSS, и эта ситуация создавала серьезные сложности для мейнтейнеров публичных проектов. Затем Парнелл и Ричардс пропали из сообщества, обе системы утратили активную поддержку, и вновь наступили «темные века». Именно в это время я открыл для себя D. Отсутствие сборщика под D2 побудило меня написать сначала простой скрипт для запуска через RDMD, а потом полноценную программу под названием Cook.
Программа автоматически сканировала структуру модулей проекта и кэшировала зависимости между модулями, так что циклы пересборки были очень быстрые. В отличие от DUB, Cook следовала идее инкрементальной сборки: все D-модули компилировались в отдельные объектные файлы, и пересобирались только те модули, которые были изменены (плюс все зависящие от них, так как в D нет деления на интерфейсные файлы и файлы реализации — если изменились шаблонные сущности, то нужно пересобирать код, который их использует).
В Cook я тоже использовал собственный формат conf-файлов — JSON в те времена был еще не так популярен, да и не очень он удобен для конфигов, если честно. Cook могла работать без конфига, если проект не использует специфичные настройки тулчейна. В конфиге можно было указать пути к компилятору и линкеру, указать флаги (cflags, lflags), переопределить команды компиляции и линковки и многое другое — громадным преимуществом Cook была возможность запускать разные версии компилятора. Вот как выглядел мой типичный кроссплатформенный конфиг:
windows.compiler_dir: "C:/dlang/dmd-2.067/windows";
linux.compiler_dir: "/opt/dlang/dmd-2.067/linux";
linux.compiler: "%compiler_dir%/bin32/dmd";
linux.linker: "%compiler_dir%/bin32/dmd";
windows.compiler: "%compiler_dir%/bin/dmd";
windows.linker: "%compiler_dir%/bin/dmd";
windows.obj.path: "o_windows";
linux.obj.path: "o_linux";
Формат конфигов представлял собой, по сути, мини-DSL с поддержкой любых кастомных переменных (не такой мощный, как в CMake, но все же получше, чем INI). Для переменных поддерживались платформ-префиксы (linux., windows.). Подобно другим старым сборщикам, Cook поддерживал мультитаргетные проекты. Еще он мог загружать зависимости из git-репозиториев и подключать к проекту зависимости, хранящиеся локально. Его можно было даже настроить для кросс-компиляции windows-программ под Linux при помощи Wine!
Получилась до того удобная штука, что я использовал Cook аж до конца десятых, предпочитая ее DUB, и прекратил разработку лишь в 2019 году, когда уже стало ясно, что DUB теперь полноправный стандарт. Cook прекрасно работает до сих пор — можете скачать, собрать и протестировать: https://github.com/gecko0307/cook2. Есть определенные задачи, где она, имхо, подойдет лучше, чем DUB — например, при сборке в экзотические целевые платформы с использованием LDC.
Не могу сказать, что я доволен DUB на 100%, есть задачи, которые он не покрывает — впрочем, как и все альтернативные сборщики. Например, до сих пор нет инструментария для автоматической интеграции в проект библиотек, написанных на других языках. Но эта проблема, судя по всему, в общем случае нерешаема.
Об администрировании сервера
Сегодня, в эпоху облачных провайдеров и SaaS, управлять сервером самостоятельно — крайне нишевое занятие. Для этого нужно очень хорошо разбираться в Linux и его многочисленных системных компонентах, которые, к тому же, постоянно обновляются и меняются, из-за чего знания и опыт быстро устаревают. Я много лет пользуюсь Linux, но и то не знаю всех тонкостей, постоянно учусь. Сама система принципиально несложная и понятная, но в ней постоянно появляется что-то новое, какие-то дополнительные слои абстракции. Linux многолик, его можно использовать в самых разных контекстах — отсюда и сложность. Ну и, конечно, знать систему на уровне десктопа — это одно, а админить по SSH — слегка другое.
(далее…)C3: неужели наконец-то нормальный C-подобный язык?
Современная замена C — это то, чего очень не хватает всем, кто пишет что-то для десктопа с нуля, не полагаясь на популярнные платформы типа веба, Java/.Net, скриптовых языков и т.д. До настоящего времени реального аналога C, можно сказать, не было вовсе (исключением является BetterC-режим D, но это все-таки не отдельный язык, а подмножество, и он не для «зашедших с улицы», а совсем наоборот — для самых опытных программистов на D). Go и Rust не предлагать! 🤣
И вот, захожу я, как обычно, в ньюсгруппу d.D и вижу ссылку на C3: https://c3-lang.org. «Продать» мне что-то новомодное сложно, но язык зацепил! Я тестировал еще не все фичи, но вот что понравилось практически сразу:
- Компилятор довольно легко установить. Вначале, правда, выкачивается майкрософтовский SDK, но после этого компилятор становится самостоятельным и Студию не требует;
- Не нужна отдельная система сборки, компилятор сам выполняет ее функции;
- Простая и вменяемая система типов, полностью совместимая с C без костылей;
- Векторы, матрицы и кватернионы в стандартной библиотеке — бесценно! Сразу уйма работы отпадает при написании игрового движка;
- Вообще, в целом, читаемая и красивая стандартная либа. Открываешь любой модуль, и все понятно;
- Управление памятью, чем-то похожее на то, что я делаю в dlib (аллокаторы, универсальный new). Сборщика мусора нет;
- Красивая обработка ошибок со встроенным Optional и проверкой на null на уровне синтаксиса. Optional — это просто модификатор типа: если его использовать, то компилятор тупо не дает прочитать такую переменную без предварительного null-чекинга. Можно его делать самостоятельно, а можно просто использовать оператор «!!», тогда компилятор вставит проверку сам. Все выглядит очень просто и читаемо;
Конечно, многого пока не хватает — например, нет менеджера пакетов. Биндинги к некоторым популярным библиотекам есть тут, но я пока не разобрался, как они линкуются, документации по этой теме нет. Нативных библиотек, ясное дело, тоже выбор пока совсем минимальный. Еще один жирный минус — не поддерживается компиляция в bare metal, а без этого язык нельзя назвать системным, и стопроцентной заменой C он считаться, строго говоря, не может.
Обновления
BindbC-Assimp
Биндинг к Assimp 5 размещен на GitHub и доступен в качестве DUB-пакета. К сожалению, название bindbc-assimp занято заброшенным и несуществующим ныне проектом, поэтому пришлось зарегать bindbc-assimp5.
Оптимизация блога
Я настроил объектный кэш на основе Redis, а также добавил HTML-кэш и заголовок Cache-Control, что заметно ускорило загрузку страниц блога. Было исправлено множество мелких проблем верстки. Все архивные игры теперь размещены на одном сервере с блогом.
Тема, которую я использую, теперь также доступна на GitHub. Это форк WPEX Blogger 1.2 от WPExplorer, в котором я внес исправления для совместимости с PHP 8, исправил поиск в мобильном меню, добавил новые переводы на русский, а также внес патч, исправляющий совместимость с плагином Code Syntax Block.
Поддержка Assimp
Библиотека Assimp — относительно тяжеловесное, но самое функциональное решение для загрузки 3D-моделей. У меня наконец-то дошли руки добавить поддержку Assimp 5+ в Dagon как расширение dagon:assimp, благодаря чему можно будет использовать в движке модели форматов FBX, Collada, 3DS и многих других. Пока загружаются только меши, но в планах добавить поддержку материалов, узлов и анимации.
Перед загрузкой модели можно задать кастомные флаги постпроцессора:
AssimpAsset aModel;
override void beforeLoad()
{
aModel = this.addAssimpAsset("assets/cacodemon.fbx");
aModel.loaderOption = aiPostProcessSteps.Triangulate
| aiPostProcessSteps.FlipUVs;
}
После этого можно использовать массив мешей aModel для рендеринга:
auto e = addEntity();
e.drawable = aModel.meshes[0];
Новый блог
Я со своим блогом вынужден переехать во второй раз. К сожалению, Hostingru, на котором я уже долгое время держу большинство своих сайтов, стремительно скатился во второсортный хостинг с чуть ли не еженедельными даунтаймами. Сломанный FTP, потери данных, проблемы с доступом к cPanel — с 2019 года я повидал все. Я решил перейти на нидерландский VPS с Linux, на котором у меня уже почти год как крутятся личные облачные сервисы — доволен абсолютно, никаких проблем ни разу не испытывал. К сожалению, это означает, что блог DLangGamedev прекращает свое существование, так как переносить старую базу постов я не буду (там слишком много устаревшего, куча проблем, унаследованных еще от миграции с Blogger). Начну все с чистого листа под своим личным брендом PixelPerfect. Спешу заверить, что тематика блога радикально не меняется — я все так же буду писать о своем опыте разработки на D и комментировать то, что делаю на GitHub. Но PixelPerfect — это больше, чем геймдев: новый блог станет станет универсальным домом для всех моих профессиональных интересов.