Исправление мобильного меню в WordPress


document.addEventListener('DOMContentLoaded', function() {
    new navMenu('primary');
    new navMenu('woo');
});

Если у вас тоже несколько лет не открывалось меню блога на iOS/Android в вашем блоге на WordPress, при использовании темы Seedlet, то просто добавьте:
В функцию замыкание файла wp-content/themes/seedlet/assets/js/primary-navigation.js, рядом с дефолтной подпиской window addEventListener ‘load’.

Номер 2

Товарищи, гордость берет за проекты которые были созданы на основе Flame Steel Framework 1 и конкретно на Flame Steel Engine 1, а именно Death-Mask, Cube Art Project, так как всё это задумывалось как большой эксперимент, создания мультимедия фреймворка в одиночку, способного работать на наибольшем количестве платформ. Считаю эксперимент завершился удачно сразу после выхода Cube Art Project.

Теперь о решениях к которым я пришел в ходе разработки новых проектов на FSFramework 1

Во время разработки Space Jaguar и шутера Space Jaguar Galaxy Bastards, стало понятно что инструменты Flame Steel Framework уже устарели, не успев даже стать хоть сколько-нибудь удобными.

Поэтому я принял решение разрабатывать полностью новый Flame Steel Framework 2. Основным решением будет переход на свой язык-транспайлер Rise 2, также архитектурно больше не будет использоваться система компонентов (ECS), т.к. она оказалась нужна только в рамках игровой логики с большой динамикой. По этой причине во Flame Steel Framework 2 система компонентов будет возможна только во время использования скриптовых языков которые планируется внедрить (как минимум Lua и JavaScript), интересной особенностью является то, что эти языки динамичны по своей природе, поэтому дополнительное создание системы компонентов избыточно.

Следить за развитием новых проектов можно в блоге и на Gitlab:

https://gitlab.com/demensdeum/rise2

https://gitlab.com/demensdeum/flamesteelengine2

https://gitlab.com/demensdeum/flame-steel-engine-2-demo-projects

https://gitlab.com/demensdeum/space-jaguar-action-rpg

https://gitlab.com/demensdeum/space-jaguar-galaxy-bastards

Характеристики в Space Jaguar Action RPG

Первая статья про игру в разработке Space Jaguar Action RPG. В данной статье я опишу гемплейную особенность Ягуара – Характеристики.

Многие РПГ используют статичную систему характеристик персонажа, например характеристики из DnD (Сила, Телосложение, Ловкость, Интеллект, Мудрость, Обаяние), или Fallout – S.P.E.C.I.A.L (Сила, Восприятие, Выносливость, Харизма, Интеллект, Ловкость, Удача).

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

Для упрощения логики проверок, каждой характеристике задается 6 значный код английскими буквами, имя, описание. Например для владения блейдом:

bladeFightingAbility.name = "BLADFG"; 
bladeFightingAbility.description = "Blade fighting ability"; 
bladeFightingAbility.points = 3;

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

Ноу-хау? Будет ли интересно? Лично я нахожу такую систему интересной, позволяющей одновременно обеспечить свободу творчества создателям игровых модулей, и возможность переноса персонажей из разных, но похожих по характеристикам, модулей для игроков.

Скелетная анимация (Часть 2 – иерархия нод, интерполяция)

Продолжаю описывать алгоритм скелетной анимации, по мере его реализации в игровом движке Flame Steel Engine.

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

Иерархия нод

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

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

Интерполяция на CPU

В прошлой статья я описал принцип рендеринга скелетной анимации – “матрицы трансформации передаются из CPU в шейдер при каждом кадре рендеринга.”

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

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

Как упростить реализацию

Чтобы упростить отладку работы вертексного шейдера, я добавил симуляцию работы вертексного шейдера на CPU с помощью макроса FSGLOGLNEWAGERENDERER_CPU_BASED_VERTEX_MODS_ENABLED. У производителя видеокарт NVIDIA есть утилита для отладки шейдерного кода Nsight, возможно она тоже может упростить разработку сложных алгоритмов вертексного/пиксельных шейдеров, однако проверить работоспособность мне так и не довелось, хватило симуляции на CPU.

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

Источники

https://www.youtube.com/watch?v=f3Cr8Yx3GGA

Space Jaguar 3D Action RPG

Давно я не анонсировал новых проектов) Следующий проект над которым я начинаю работу – 3д экшн рпг под названием Space Jaguar (Космический Ягуар) История в sci-fi сеттинге про крутого парня по имени Джаг и его нелегкое приключение в поисках пропавшего отца. Будет 3D графика на движке Flame Steel Engine (или возможно на любом другом популярном), с использованием наработок прошлых проектов (Death Mask, Cube Art Project), комедийный сюжет со множеством отсылок, аркадными боями и боссами. О сроках релиза полной версии говорить не готов, планирую выпускать игру частями.

Репозиторий проекта:
https://gitlab.com/demensdeum/space-jaguar-action-rpg

Разработка игры для ZX Spectrum на C

Эта непутевая заметка посвящена разработке игры для старого компьютера ZX Spectrum на C. Давайте взглянем на красавца:

Он начал производится в 1982 году, и выпускался до 1992 года. Технические характеристики машины: 8-битный процессор Z80, 16-128кб памяти и прочие экстеншены, например звуковой чип AY-3-8910.

В рамках конкурса Yandex Retro Games Battle 2019 для данной машины я написал игру под названием Interceptor 2020. Так как учить ассемблер для Z80 времени не было, я решил разработать ее на языке Си. В качестве тулчейна я выбрал готовый набор – z88dk, который содержит компиляторы Си, и много вспомогательных библиотек для ускорения реализации приложений для Спектрума. Он также поддерживает множество других Z80 машин, например MSX, калькуляторов Texas Instruments.

Далее я опишу свой поверхностный полет над архитектурой компьютера, тулчейном z88dk, покажу как удалось реализовать ООП подход, использовать паттерны проектирования.

Особенности установки

Установку z88dk следует проводить по мануалу из репозитория, однако для пользователей Ubuntu я хотел бы отметить особенность – если у вас уже установлены компиляторы для Z80 из deb пакетов, то следует их удалить, так как z88dk по умолчанию будет обращаться к ним из папки bin, из-за несовместимости версий тулчейн-компилятор вы скорее всего ничего не сможете собрать.

Hello World

Написать Hello World очень просто:

#include 

void main()
{
    printf("Hello World");
}

Собрать в tap файл еще проще:

zcc +zx -lndos -create-app -o helloworld helloworld.c

Для запуска используйте любой эмулятор ZX Spectrum с поддержкой tap файлов, например онлайн:
http://jsspeccy.zxdemo.org/

Рисуем на картинку на весь экран

tl;dr Картинки рисуются тайлами, тайлами размера 8×8 пикселей, сами тайлы встраиваются в шрифт спектрума, затем строкой из индексов печатается картинка.

Библиотека вывода спрайтов и тайлов sp1 выводит тайлы с помощью UDG. Картинка переводится в набор отдельных UDG (тайлы), затем собирается на экране с помощью индексов. Следует помнить что UDG используется для вывода текста, и если ваша картинка содержит очень большой набор тайлов (например больше 128 тайлов), то придется выходить за границы набора и стирать дефолтный спектрумовский шрифт. Чтобы обойти это ограничение, я использовал базу от 128 – 255 с помощью упрощения изображений, оставляя оригинальный шрифт на месте. Об упрощении картинок ниже.

Для отрисовки полноэкранных картинок нужно вооружиться тремя утилитами:
Gimp
img2spec
png2c-z88dk

Есть путь настоящих ZX мужчин, настоящих ретро-воинов это открыть графический редактор, используя палитру спектрума, зная особенности вывода картинки, подготовить ее вручную и выгрузить с помощью png2c-z88dk или png2scr.

Путь попроще – взять 32 битное изображение, переключить в Gimp количество цветов до 3-4-х, слегка подредактировать, затем импортировать в img2spec для того чтобы не работать с цветовыми ограничениями вручную, экспортировать png и перевести в Си массив с помощью png2c-z88dk.

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

В результате вы получите h файл, который содержит количество уникальных тайлов, если их больше ~128, то упрощайте в Gimp картинку (увеличьте повторяемость) и проводите процедуру экспорта по новой.

После экспорта вы в прямом смысле загружаете “шрифт” из тайлов и печатаете “текст” из индексов тайлов на экране. Далее пример из “класса” рендера:

// грузим шрифт в память
    unsigned char *pt = fullscreenImage->tiles;

    for (i = 0; i < fullscreenImage->tilesLength; i++, pt += 8) {
            sp1_TileEntry(fullscreenImage->tilesBase + i, pt);
    }

    // ставим курсор в 0,0
    sp1_SetPrintPos(&ps0, 0, 0);

    // печатаем строку
    sp1_PrintString(&ps0, fullscreenImage->ptiles);

Рисуем спрайты на экране

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

Рисуем в Gimp монохромную png картинку 16×16, далее с помощью png2sp1sprite переводим ее в ассемблерный файл asm, в Си коде объявляем массивы из ассемблерного файла, добавляем файл на этапе сборки.

После этапа объявления ресурса спрайта, его надо добавить на экран в нужную позицию, далее пример кода “класса” игрового объекта:

    struct sp1_ss *bubble_sprite = sp1_CreateSpr(SP1_DRAW_MASK2LB, SP1_TYPE_2BYTE, 3, 0, 0);
    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2,    SP1_TYPE_2BYTE, col2-col1, 0);
    sp1_AddColSpr(bubble_sprite, SP1_DRAW_MASK2RB,  SP1_TYPE_2BYTE, 0, 0);
    sp1_IterateSprChar(bubble_sprite, initialiseColour);

По названиям функций можно примерно понять смысл – аллоцируем память для спрайта, добавляем две колонки 8×8, добавляем цвет для спрайта.

В каждом кадре проставляется позиция спрайта:

sp1_MoveSprPix(gameObject->gameObjectSprite, Renderer_fullScreenRect, gameObject->sprite_col, gameObject->x, gameObject->y);

Эмулируем ООП

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

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

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

Также стоит отметить упрощение решения вопросов связанных с архитектурой приложения, ведь 80% архитектурных проблем было решено компьютерными-учеными еще в прошлом веке и описано в литературе посвященной паттернам проектирования. Далее я опишу способы добавить похожий на ООП синтаксис в Си.

За основу хранения данных экземпляра класса удобнее взять структуры Си. Конечно можно использовать байтовый буфер, создать свою собственную структуру для классов, методов, но зачем переизобретать колесо? Ведь мы и так переизобретаем синтаксис.

Данные класса

Пример полей данных “класса” GameObject:

struct GameObjectStruct {
    struct sp1_ss *gameObjectSprite;
    unsigned char *sprite_col;
    unsigned char x;
    unsigned char y;
    unsigned char referenceCount;
    unsigned char beforeHideX;
    unsigned char beforeHideY;
};
typedef struct GameObjectStruct GameObject;

Сохраняем наш класс как “GameObject.h” делаем #include “GameObject.h” в нужном месте и пользуемся.

Методы класса

Возьмем на вооружение опыт разработчиков языка Objective-C, сигнатура метода класса будут представлять из себя функции в глобальном скопе, первым аргументом всегда будет передаваться структура данных, далее идут аргументы метода. Далее пример “метода” “класса” GameObject:

void GameObject_hide(GameObject *gameObject) {
    gameObject->beforeHideX = gameObject->x;
    gameObject->beforeHideY = gameObject->y;
    gameObject->y = 200;
}

Вызов метода выглядит так:

GameObject_hide(gameObject);

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

Работа с памятью

Ручное управление памятью вида с помощью malloc и free обернутых в макросы new и delete для соответствия с C++:

#define new(X) (X*)malloc(sizeof(X))
#define delete(X) free(X)

Для объектов которые используются несколькими классами сразу, реализовано полу-ручное управление памятью на основе подсчета ссылок, по образу и подобию старого механизма Objective-C Runtime ARC:

void GameObject_retain(GameObject *gameObject) {
    gameObject->referenceCount++;
}

void GameObject_release(GameObject *gameObject) {
    gameObject->referenceCount--;

    if (gameObject->referenceCount < 1) { sp1_MoveSprAbs(gameObject->gameObjectSprite, &Renderer_fullScreenRect, NULL, 0, 34, 0, 0);
        sp1_DeleteSpr(gameObject->gameObjectSprite);
        delete(gameObject);
    }
}

Таким образом каждый класс должен объявлять использование общего объекта с помощью retain, освобождать владение через release. В современном варианте ARC используется автоматическое проставление вызовов retain/release.

Звучим!

На Спектруме есть пищалка способная воспроизводить 1-битовую музыку, композиторы того времени умели воспроизводить на ней до 4-х звуковых каналов одновременно.

Spectrum 128k содержит отдельный звуковой чип AY-3-8910, на котором можно воспроизводить трекерную музыку.

Для использования пищалки в z88dk предлагается библиотека

Что предстоит узнать

Мне было интересно ознакомиться со Спектрумом, реализовать игру средствами z88dk, узнать много интересных вещей. Многое мне еще предстоит изучить, например ассемблер Z80, так как он позволяет использовать всю мощь Спектрума, работу с банками памяти, работу со звуковым чипом AY-3-8910. Надеюсь поучаствовать в конкурсе на следующий год!

Ссылки

https://rgb.yandex
https://vk.com/sinc_lair
https://www.z88dk.org/forum/

Исходный код

https://gitlab.com/demensdeum/zx-projects/tree/master/interceptor2020

Death-Mask Wild Beta

Игра Death-Mask переходит в статус публичной беты (wild beta)
Переработан экран главного меню игры, добавлен вид на синюю зону технолабиринта, с приятной музыкой на фоне.

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

Хороший, плохой, мерзкий синглтон

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


Wolf in sheep’s clothing by SarahRichterArt

История происходит в альтернативной вселенной, все совпадения случайны…

Погладь кота на дому с Cat@Home

У каждого человека иногда в жизни возникает непреодолимое желание погладить кота. Аналитики всего мира пророчат что первый стартап создавший приложение по доставке и аренде котиков станет крайне популярным, в недалекой перспективе будет куплен компанией Moogle за триллионы долларов. Вскоре так и происходит – парень из Тюмени создает приложение Cat@Home, и вскоре становится триллиардером, компания Moogle получает себе новый источник прибыли, а миллионы застрессованых людей получают возможность заказать кота на дом для дальнейшего глаженья и успокоения.

Атака клонов

Крайне богатый дантист из Мурманска Алексей Голобородько, впечатлившись статьей про Cat@Home из Фorbes, решает что тоже хочет быть астрономически богатым. Для достижения этой цели, через своих друзей, он находит компанию из Голдфилда – Wakeboard DevPops которая оказывает услуги по разработке ПО, он заказывает разработку клона Cat@Home у них.

Команда победителей

Проект называют Fur&Pure, поручают талантливой команде разработчиков из 20 человек; далее сосредоточимся на группе мобильной разработки из 5 человек. Каждый член команды получает свою часть работы, вооружившись agile-ом и скрамом, команда завершает разработку в срок (за полгода), без багов, релизит приложение в iStore, где ее оценивают 100.000 пользователей на 5, много комментариев о том как прекрасно приложение, как прекрасен сервис (Альтернативная вселенная как-никак). Коты выглажены, приложение выпущено, вроде-бы все идет хорошо. Однако компания Moogle не торопится покупать стартап за триллионы долларов, потому что в Cat@Home уже появились не только коты но и собаки.

Собака лает, караван идет

Владелец приложения решает что пора добавить в приложение собак, обращается за оценкой в компанию и получает примерно минимум полгода на добавление собак в приложение. Фактически приложение будет написано с нуля снова. За это время Moogle добавит в приложение змей, пауков и морских свинок, а Fur&Pur получит только собак.
Почему так получилось? Во всем виновато отсутствие гибкой архитектуры приложения, одним из самых распространенных факторов является антипаттерн проектирования Singleton.

А что такого?

Для того чтобы заказать кота на дом, потребителю нужно создать заявку и отправить ее в офис, где в офисе ее обработают и пришлют курьера с котом, курьер уже получит оплату за услугу.
Один из программистов решает создать класс “ЗаявкаНаКота” с необходимыми полями, выносит этот класс в глобальное пространство приложения через синглтон. Зачем он это делает? Для экономии времени (копеечная экономия получаса), ведь проще вынести заявку в общий доступ, чем продумывать архитектуру приложения и использовать dependency injection. Дальше остальные разработчики подхватывают этот глобальный объект и привязывают свои классы к нему. Например все экраны сами обращаются к глобальному объекту “ЗаявкаНаКота” и показывают данные по заявке. В итоге такое монолитное приложение тестируется и сдается в релиз.
Все вроде хорошо, но вдруг появляется заказчик с требованием добавить в приложение заявки на собак. Команда судорожно начинает оценивать сколько компонентов в системе затронет данное изменение. По окончанию анализа оказывается что нужно переделать от 60 до 90% кода, чтобы научить приложение принимать в глобальном объекте-синглтоне не только “ЗаявкуНаКота” но и “ЗаявкуНаСобаку”, оценивать добавление остальных животных на данном этапе уже бесполезно, справиться хотя бы с двумя.

Как не допустить синглтон

Во-первых, на этапе сбора требований явно указать необходимость в создании гибкой, расширяемой архитектуры. Во-вторых, стоит проводить независимую экспертизу кода продукта на стороне, с обязательным исследованием слабых мест. Если вы разработчик и вы любите синглтоны, то предлагаю одуматься пока не поздно, иначе бессонные ночи и выжженные нервы обеспечены. Если вы работаете с проектом по наследству, в котором много синглтонов, то попытайтесь избавиться от них как можно быстрее, или от проекта.
Переходить с антипаттерна синглтонов-глобальных объектов/переменных нужно на dependency injection – простейший паттерн проектирования в котором все необходимые данные задаются экземпляру класса на этапе инициализации, без дальнейшей необходимости быть привязанным к глобальному пространству.

Источники

https://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons
http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
https://blog.ndepend.com/singleton-pattern-costs/

Скрипя шестеренками

Ах муза, как сложно тебя поймать порой.
Разработка Death-Mask, и связанных фреймворков (Flame Steel Core, Game Toolkit и др.) приостанавливается на несколько месяцев, для того чтобы определиться с художественной частью игры, музыкальным, звуковым сопровождением, продумыванием геймплея.
В планах – создать редактор для Flame Steel Game Toolkit, написать интерпретатор игровых скриптов (на основе синтаксиса Rise), реализовать игру Death-Mask для максимально большого количества платформ.
Сложнейший этап пройден – на практике доказана возможность написания своего собственного кроссплатформенного игрового движка, своего IDE, набора библиотек.
Перехожу к этапу создания действительно продуманного, интересного проекта, следите за новостями.

Бьемся с Малевичем, черные квадраты OpenGL

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

Сегодня я опишу по какой причине меня посетил черный квадрат, найденные проблемы из-за которых OpenGL ничего не рисует на экране, а иногда и вообще делает окно прозрачным.

Используй инструменты

Для отладки OpenGL мне помогли два инструмента: renderdoc и apitrace. Renderdoc – инструмент для отладки процесса рендеринга OpenGL, просматривать можно все – вертексы, шейдеры, текстуры, отладочные сообщения от драйвера. Apitrace – инструмент для трейсинга вызовов графического API, делает дамп вызовов и показывает аргументы. Также есть великолепная возможность сравнивать два дампа через wdiff (или без него, но не так удобно)

Проверяй с кем работаешь

У меня есть операционная система Ubuntu 16.10 со старыми зависимостями SDL2, GLM, assimp, GLEW. В последней версии Ubuntu 18.04 я получаю сборку игры Death-Mask которая ничего не показывает на экране (только черный квадрат). При использовании chroot и сборке в 16.10 я получаю рабочую сборку игры с графикой.

Похоже что-то сломалось в Ubuntu 18.04

LDD показал линковку к идентичным библиотекам SDL2, GL. Прогоняя нерабочий билд в renderdoc, я увидел мусор на входе в вертексный шейдер, но мне нужно было более солидное подтверждение. Для того чтобы разобраться в разнице между бинариками я прогнал их оба через apitrace. Сравнение дампов показало мне что сборка на свежей убунте ломает передачу матриц перспективы в OpenGL, фактически отправляя туда мусор:

Матрицы собираются в библиотеке GLM. После копирования GLM из 16.04 – я снова получил рабочий билд игры. Проблема оказалась в разнице инициализации единичной матрицы в GLM 9.9.0, в ней необходивно явно указывать аргумент mat4(1.0f) в конструкторе. Поменяв инициализацию и отписав автору библиотеки, я принялся делать тесты для FSGL. в процессе написания которых я обнаружил недоработки в FSGL, их опишу далее.

Определись ты кто по жизни

Для корректной работы с OpenGL нужно в добровольно принудительном порядке запросить контекст определенной версии. Так это выглядит для SDL2 (проставлять версию нужно строго до инициализации контекста):

    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

Например Renderdoc не работает с контекстами ниже 3.2. Хочется отметить что после переключения контекста высока вероятность увидеть тот самый черный экран. Почему?
Потому что контекст OpenGL 3.2 обязательно требует наличие VAO буфера, без которого не работают 99% графических драйверов. Добавить его легко:

    glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

Не спи, замерзнешь

Также я встретился с интересной проблемой на Kubuntu, вместо черного квадрата у меня выводился прозрачный, а иногда все рендерилось корректно. Решение этой проблемы я нашел на Stack Overflow:
https://stackoverflow.com/questions/38411515/sdl2-opengl-window-appears-semi-transparent-sometimes

В коде тестового рендера FSGL тоже присутствовал sleep(2s); Так вот на Xubuntu и Ubuntu я получал корректный рендер и отправлял приложение спать, однако на Kubuntu я получил прозрачный экран в 80% случаев запуска из Dolphin и 30% запусков и терминала. Для решения данной проблемы я добавил рендеринг в каждом кадре, после опроса SDLEvent, как это рекомендуется делать в документации.

Код теста:
https://gitlab.com/demensdeum/FSGLtests/blob/master/renderModelTest/

Поговори с драйвером

OpenGL поддерживает канал связи между приложением и драйвером, для его активации нужно включить флаги GL_DEBUG_OUTPUT, GL_DEBUG_OUTPUT_SYNCHRONOUS, проставить оповещение glDebugMessageControl и привязать каллбек через glDebugMessageCallback.
Пример инициализации можно взять здесь:
https://github.com/rock-core/gui-vizkit3d/blob/master/src/EnableGLDebugOperation.cpp

Не бойся, посмотри как он увеличивается

В данной заметке я расскажу о своих злоключениях с умными указателями shared_ptr. После реализации генерации следующего уровня в своей игре Death-Mask, я заметил утечку памяти. Каждый новый уровень давал прирост + 1 мегабайт к потребляемой оперативной памяти. Очевидно что какие-то объекты оставались в памяти и не освобождали ее. Для исправления данного факта необходимо было реализовать корректную реализацию ресурсов при перегрузке уровня, чего видимо сделано не было. Так как я использовал умные указатели, то вариантов решения данной задачи было несколько, первый заключался в ручном отсмотре кода (долго и скучно), второй же предполагал исследование возможностей дебагера lldb, исходного кода libstdc++ на предмет возможности автоматического отслеживания изменений счетчика.

В интернете все советы сводились к тому чтобы вручную отсматривать код, исправить и бить себя плетями после нахождения проблемной строчки кода. Также предлагалось реализовать свою собственную систему работы с памятью, как это делают все крупные проекты разрабатываемые еще с 90-х и нулевых, до прихода умных указателей в стандарт C++11. Мною была предпринята попытка использовать брейкпоинты на конструкторе копии всех shared_ptr, после нескольких дней ничего дельного не получилось. Была идея добавить логирование в библиотеку libstdc++, однако трудозатраты (о)казались чудовищными.


Cowboy Bebop (1998)

Решение пришло мне в голову внезапно в виде отслеживания изменений приватной переменной shared_ptr – use_count. Сделать это можно с помощью встроенных в lldb ватчпоинтов (watchpoint) После создания shared_ptr через make_shared, изменения счетчика в lldb можно отслеживать с помощью строки:

watch set var camera._M_refcount._M_pi->_M_use_count

Где “camera” это shared_ptr объект состояние счетчика которого необходимо отследить. Конечно внутренности shared_ptr будут различаться в зависимости от версии libstdc++, но общий принцип понять можно. После установки ватчпоинта запускаем приложения и читаем стектрейс каждого изменения счетчика, потом отсматриваем код (sic!) находим проблему и исправляем. В моем случае объекты не освобождались из таблиц-кешэй и таблиц игровой логики. Надеюсь данный метод поможет вам разобраться с утечками при работе с shared_ptr, и полюбить этот инструмент работы с памятью еще больше. Удачного дебага.

Games Vision #3

Третий выпуск непостоянной рубрики об играх Games Vision.

Observer (ПК и консоли, Bloober Team) – киберпанк-хоррор от доблестных поляков. Короткий и очень атмосферный ужастик с Рутгером Хауэром в главной роли. Мне, как фанату киберпанка, в игре понравилось абсолютно все. Не очень сложные загадки, очаровательные глюки главного героя, геймплей со спокойными моментами в перемешку с экшеном, возможность в буквальном смысле копаться в воспоминаниях мертвых, сюжет в стиле Призрака в Доспехах + множество отсылок к Sci-Fi попкультуре. Из минусов – перебор с гличами, иногда кажется что из-за их обилия невозможно играть, также некоторых игроков выводили из себя специфические хоррор элементы, пугающие настолько что они не могли продолжать играть.
Оценка: 8/10

Paradigm (Windows/OS X, Jacob Janerka) – квест который умудряется пародировать и смеяться над всем и сразу. Здесь есть высмеивание СССР, Америки, жанра квестов, глэм-рока, старых приставок, людей, памятников, айтишников, конусов, компьютеров, женщин, детей, родителей, художников, любви, ученых, игровой индустрии, самых игроков – вообщем всего не перечислить. Абсолютно непредсказуемый сюжет, абсурдная атмосфера и арт, не особо сложные загадки. В игре есть редкие баги и вылеты, некоторые моменты и шутки слегка предсказуемы и не оригинальны.
Оценка: 9/10

Late Shift (ПК и консоли, CtrlMovie Ltd) – интерактивный фильм. Мне действительно жаль что в принципе хорошая задумка получила столь плохую реализацию. Плохо все – сюжет, отсутствие звездных актеров, актерская игра, постоянные зависания в версии для ПК, практически нулевая вариативность (иллюзорная). Совершенно непонятно как можно было выпустить игру с таким количеством проблем в 2010-х, ведь по сути это обычный видеоплеер, всю игру можно было разместить в интернете например на youtube, но вместо этого использовали Unity и умудрились сломать даже столь мощный игровой движок. Официальный форум в Steam посвящен фиксам, хотфиксам, воркараундам и т.д. Налицо техническая катастрофа, отсутствие службы поддержки пользователей, все тестирование происходит прямо на игроках. Купленные восторженные обзоры и отзывы.
Оценка: 3/10

Saber-Plus C++ IDE

Начал разработку собственного IDE для С++ – Saber-Plus. Основные идеи нового IDE – быть простым, быстрым и *помогающим* в разработке. На данный момент исходный код доступен по лицензии MIT на GitHub, для работы с UI используется Qt. В дальнейшем планирую перенести всю разработку связанную с C++ на Saber-Plus – точно будет проведена миграция игры Death-Mask. Подробнее по пунктам:

  • Простой – планируется не добавлять больше чем нужно – например не содержать source control клиенты, встроенный терминал и подобные вещи. Функционал сосредоточен только на редактировании кода, анализе ошибок. Код редактора должен быть разбит на простые классы, которые корректно выполняют свою часть работы (Unix-way)
  • Быстрый – касается как кодовой базы IDE так и самого поведения редактора. Все действия в IDE должны быть максимально быстрыми, даже такие зачастую долгие и сложные как создание/импортирование проектов.
  • Помогающий – анализ типичных ошибок при написании, компиляции кода. Исправление ошибок, предупреждений по требованию пользователя. В планах идея добавить анализ сборки приложения на конкретной платформе и вывод справочной информации по установке нужных библиотек, компонентов.

Для сборки редактора для вашей операционной системы, нужно установить  Qt 5 SDK, загрузить код IDE из репозитория, открыть файл Saber-Plus.pro в Qt Creator и запустить сборку:

https://github.com/demensdeum/saberplus

Прототип Death Mask для Windows

Видео:

Версия для Windows:
http://demensdeum.com/games/deathMask/prototype/DeathMaskPrototype.exe

Пользователи Linux и OS X могут собрать игру из исходников:
https://github.com/demensdeum/Death-Mask

Дальше я буду добавлять геймплейные элементы, освещение, анимацию.

Flame Steel Battle Axe

С сегодняшнего дня я начинаю разработку редактора для игрового фреймворка – Flame Steel Battle Axe.

Редактор позволить редактировать сцены для игрового фреймворка Flame Steel Game Toolkit.
Я выбрал относительно молодой язык Kotlin на базе Java, для того чтобы опробовать его в боевых условиях.

Можете следить за процессом в репозитории:
https://github.com/demensdeum/FlameSteelBattleAxe

Flame Steel Core

Скриншот из последней версии Death Mask:

Выглядит на миллион долларов да?

Переименование, разбиение

Библиотека Flame Steel Engine переименована в Flame Steel Core, Game Toolkit разбит на SDL, Panda3D (Desktop) и Web (ThreeJS) библиотеки. Если в наличии есть стальные шары для сборки с помощью библиотек Flame Steel, тогда нужно сначала выбрать и собрать нужные.

Github:

https://github.com/demensdeum/Death-Mask
https://github.com/demensdeum/FlameSteelCore
https://github.com/demensdeum/FlameSteelEngineGameToolkit
https://github.com/demensdeum/FlameSteelEngineGameToolkitDesktop

Устаревшие:

https://github.com/demensdeum/FlameSteelEngineGameToolkitSDL
https://github.com/demensdeum/FlameSteelEngineGameToolkitWeb

Квантовый взлом RSA

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

Не все так страшно

На самом деле на первом этапе создания ключей мы берем два случайных числа, но числа должны делиться только на себя и единицу – простые числа.
Назовем их p и q. Далее мы должны получить число n = p *q. Оно будет использоваться для дальнейшей генерации ключей, ключи в свою очередь будут использоваться для шифрования, дешифровки сообщений. В итоговом варианте приватного и публичного ключа число n будет передано без изменений.
Допустим у нас на руках один из ключей RSA и зашифрованное сообщение. Вытаскиваем из ключа число n и начинаем его хакать.

Факторизуем n

Факторизация – разложение числа на простые множители. Сначала вытаскиваем из ключа число n (на настоящих ключах можно сделать с помощью openssl), допустим n = 35. Тогда раскладываем на простые множители n = 35 = 5 * 7, это и есть наши p и q. Теперь можно перегенерить ключи с помощью полученных p, q, дешифровать сообщение и шифровать обеспечивая видимость оригинального автора.

С кубитами не все так просто

Неужели можно поломать любой RSA так просто? На самом деле нет, числа p, q берут заведомо большими, чтобы задача факторизации на классических компьютерах заняла очень продолжительное время (10 лет в какой-то там степени)
Однако, используя квантовый алгоритм Шора, факторизовать число можно за очень малое время. На данный момент в статьях на эту тему заявлено время перемножения данного числа, тоесть фактически моментально. Для работы алгоритма Шора необходимо реализовать квантовые компьютеры, с большим количеством кубит. В 2001 году IBM разложили на простые множители число 15 с помощью 7 кубит. Так что этого момента придется ждать еще долго, к тому времени мы перейдем на пост-квантовые алгоритмы шифрования.

Потрогать Шора

Питер Шор рассказывает про свой алгоритм факторизации

Чтобы опробовать алгоритм Шора на квантовом симуляторе, вы можете установить ProjectQ, в его примеры входит реализация shor.py, позволяющая факторизовать число вводимое пользователем. На симуляторе время выполнения удручает, но вроде весело и задорно симулирует работу квантового компьютера.

Статьи:
http://www.pagedon.com/rsa-explained-simply/my_programming/
http://southernpacificreview.com/2014/01/06/rsa-key-generation-example/
https://0day.work/how-i-recovered-your-private-key-or-why-small-keys-are-bad/

Реализация RSA на Python:
https://github.com/demensdeum/RSA-Python

Квантовый генератор чисел и хак IBM Quantum Experience

Эта заметка увеличит длину вашего резюме на 5 см!

Без лишних слов о крутости квантовых компьютеров и всего такого, сегодня я покажу как сделать генератор чисел на реальном квантовом процессоре IBM.
Для этого мы будем использовать всего один кубит, фреймворк для разработки квантового ПО для python – ProjectQ, и 16 кубитовый процессор от IBM, онлайн доступ к которому открыт любому желающему по программе IBM Quantum Experience.

Установка ProjectQ

Для начала у вас должен быть Linux, Python и pip. Какие либо инструкции по установке этих базовых вещей приводить бесполезно, т.к. в любом случае инструкции устареют через неделю, поэтому просто найдите гайд по установке на официальном сайте. Далее устанавливаем ProjectQ, гайд по установке приведен в документации. На данный момент все свелось к установке пакета ProjectQ через pip, одной командой: python -m pip install –user projectq

Ставим кубит в суперпозицию

Создаем файл quantumNumberGenerator.py и берем пример генератора бинарного числа из документации ProjectQ, просто добавляем в него цикл на 32 шага, собираем бинарную строку и переводим в 32-битное число:

import projectq.setups.ibm
from projectq.ops import H, Measure
from projectq import MainEngine
from projectq.backends import IBMBackend

binaryString = ""

eng = MainEngine()

for i in range(1, 33):

 qubit = eng.allocate_qubit()

 H | qubit

 Measure | qubit

 eng.flush()

 binaryString = binaryString + str(int(qubit))

 print("Step " + str(i))

number = int(binaryString, 2)

print("\n--- Quantum 32-Bit Number Generator by demensdeum@gmail.com (2017) ---\n")
print("Binary: " + binaryString)
print("Number: " + str(number))
print("\n---")

Запускаем и получаем число из квантового симулятора с помощью команды python quantumNumberGenerator.py

Незнаю как вы, но я получил вывод и число 3974719468:

--- Quantum 32-Bit Number Generator by demensdeum@gmail.com (2017) ---

Binary: 11101100111010010110011111101100
Number: 3974719468

---

Хорошо, теперь мы запустим наш генератор на реальном квантовом процессоре IBM.

Хакаем IBM

Проходим регистрацию на сайте IBM Quantum Experience, подтверждаем email, в итоге должен остаться email и пароль для доступа.
Далее включаем айбиэмовский движок, меняем строку eng = MainEngine() -> eng = MainEngine(IBMBackend())
В теории после этого вы запускаете код снова и теперь он работает на реальном квантовом процессоре, используя один кубит. Однако после запуска вам придется 32 раза набрать свой email и пароль при каждой аллокации реального кубита. Обойти это можно прописав свой email и пароль прямо в библиотеки ProjectQ.

Заходим в папку где лежит фреймворк ProjectQ, ищем файл с помощью grep по строке IBM QE user (e-mail).
В итоге я исправил строки в файле projectq/backends/_ibm/_ibm_http_client.py:

email = input_fun('IBM QE user (e-mail) > ') -> email = "quantumPsycho@aport.ru"

password = getpass.getpass(prompt='IBM QE password > ') -> password = "ilovequbitsandicannotlie"

Напишите свой email и password со-но.

После этого IBM будет отправлять результаты работы с кубитом онлайн прямо в ваш скрипт, процесс генерации занимает около 20 секунд.

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

Статья на похожую тему:
Introducing the world’s first game for a quantum computer

Зачем делать игровой движок в 2017 году?

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

Я подготовил отдельную статью с обзором текущего рынка геймдева, описал причины сподвигнувшие меня на создание Flame Steel Engine:

Reasons to Make New Game Engine in 2017

Красивые и пустые

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

Вот так я себя чувствую когда играю в любую игру от Blizzard. Я вижу много людей которые не могут играть в игры старой школы, не могут играть во что-то действительно оригинальное, не шаблонное (Deadly Premonition или Papers Please) зато все любят игры Blizzard.

Знакомство с их играми на PC я начал со Starcraft. После диких и аркадных Command & Conquer, геймплей мне показался очень размеренным, успокаивающим. Ограничение на количество юнитов, копание в микро-нано операциях меня лично очень усыпляют. Дальше была красивая, но пустая кликер игра – Diablo 2. Хорошая графика, генерируемые уровни, и ноль геймплея, абсолютно медитативное и пустое времяпрепровождение. Однако мои друзья крепко засели в старкрафте и диабле. В начале нулевых вышел крышесносный Warcraft 3. Одиночная компания мне тогда очень понравилась. Однако мультиплеер очень похож на Starcraft и потому очень уныл. Далее был не менее красивый, пустой Starcraft 2. Некоторое время я играл в f2p Hearthstone – эта игра похожа на игральный автомат, первое время ты выигрываешь, появляется вера в себя, но потом к тебе приходят разработчики с предложение купить несколько колод по цене 500 ₽. Твой скилл ничего не зарешает, решает только количество денег потраченных на виртуальные колоды.

Недавно я купил Overwatch, шутер от Blizzard. Мне понравилась героиня Mei, артом, косплеем на которую засыпаны все соцсети, в итоге общая волна рекламы в гик сообществах выбросила меня на берег игроков Overwatch.

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

Единственная игра Blizzard которая мне по настоящему понравилась – Rock’n’Roll Racing. Там действительно есть геймплей, но у меня подозрение что в этом заслуга не разработчика, а издателя – Interplay, скорее всего Interplay помогли Blizzard сделать из игры что-то по настоящему играбельное.

Games Vision #2

Непостоянная рубрика Games Vision.
Пишу краткие обзоры на игры в которые играл в последнее время

wsunhd
SIM
aka Sara is Missing (Android, Monsoon Lab) – ты находишь телефон девушки по имени Сара. Внутри телефона есть встроенный помощник IRIS, она хочет найти свою хозяйку и просит тебя ей в этом помочь. Задача понять что творилось в голове Сары из ее переписки, фоточек и видео, найти где она находится. Игра очень оригинальная и достаточно пугающая. Минус в том что нет локализации на русский и другие языки, нет версии для iOS, хотя очевидно что интерфейс игры копирует продукцию Apple (IRIS – SIRI) Также игра очень короткая.
Оценка 7/10

unnamed
The End of The World
(Android, Sean Wenham) – игра про расставание – парня бросила девушка, теперь он бродит в поисках вина и спит под мостом, вспоминая моменты когда они были вместе. Умилительные моменты воспоминаний, грустная музыка, переход в белое, в принципе отличная игра для женской аудитории и некоторых пацанов. Мне не понравилась бюджетная графика с претензией на оригинальность (напоминает Another World Эрика Шайи), нулевой геймплей, попытки выбить из игрока слезки, предсказуемость, десять минут прохождения. Любителям ванили рекомендую.
Оценка: 5/10

unnamed

Werewolf Tycoon (Android, Joe Williamson) – игра про оборотня который ест людей в городском парке. Графика и геймплей здесь веселые – детские, цвета светлые без мрачных тонов, отсутствие крови и люди похожие на круглые кексики со смешными анимациями. Раунды короткие и простые, из врагов только журналисты с фотоаппаратами. Звучит, выглядит и играется очень весело. Из минусов – низкая сложность, просмотр рекламы за отмену Game Over, не работает механизм вывода набранных очков в социальные сети.
Оценка: 6/10

Games Vision #1

Непостоянная рубрика Games Vision.
В этой статье я напишу краткие обзоры на игры в которые играл в последнее время.

jansen

Даже не думайте что у этого парня есть эмоции, просто он иногда делает вид что они есть.

Deus Ex Mankind Divided (PC, Square Enix) – игра про полу-человека Адама Дженсена который отдыхает в Праге и попутно спасает мир.
Хорошая графика, высокие системные требования, предсказуемый сюжет, нестандартная работа художников – все здесь. Игра предлагает множество вариантов прохождения, например мне удалось получить ачивмент “пацифист”, за то что я никого не убил за все прохождение, в том числе и боссов.
Мне понравились отсылки к поп культуре “The Void Which Binds“, “IRON MADE in China” и др. Не понравилось огромное количество текста – воды, всякие email хранящие пароли от дверей и переписка персонажей, текст абсолютно пустой и не интересный. На момент прохождения игра постоянно вылетала в режиме DirectX 12, автосейвы ломались, патчи похоже выпускаются до сих пор. В DLC я решил не играть т.к. уже основную игру проходил около 2х недель, выбившись из своей привычной пустой жизни.
Оценка 8/10

slayin

Slayin (Android, FDG) – незаурядная аркада в пиксельном стиле для мобилок. Нужно бегать и убивать монстров, покупая экипировку в магазине. В этой игре мне понравился арт, очень понравилась чиптюн музыка, похоже на аркады для NES, удобное управление. Сама же игра расстроила тем что геймплей происходит не дальше одной сцены на экране, невозможностью перемещаться по большому уровню.
Оценка 5/10

swordxolan

Sword of Xolan (Android, Alper Sarıkaya) – аркадный платформер в пиксельном стиле для мобилок. Рыцарь или самурай бегает по уровню и спасает людей из железных клеток. Достаточно интересный геймплей, удобное управление, большие уровни. Расстраивает общая бюджетность игры, дешевый арт, дешевый звук, зацикленная музыка.
Оценка 6/10

bardstale

The Bard’s Tale (Android, inXile entertainment) – ремастер экшн рпг для мобилок. Нестандартная рпг со смешными сценами и диалогами. На диске с игрой было написано “переверните диск чтобы увидеть что-то ужасное”, на обратной стороне была зеркальная сторона диска. В свое время я пропустил эту игру на PC из-за Neverwinter Nights, но теперь могу играть в нее на мобилке в автобусе. Для современного геймера явно не хватает точек куда идти и что делать, но за это я и люблю игры старой школы, в них действительно нужно играть. Также отсутствует возможность сохраняться в любой точке, что для мобильной игры критично. Музыка, арт, мне нравится все, однако текущее управление на экране телефона я считаю неудобным. И конечно же это не новая игра, а просто переиздание на мобильные платформы, что лично я считаю большим минусом.
Оценка 7/10

Разбавляя ECS


Commission: Mad Scientist by Culpeo-Fox on DeviantArt

В этой статье я примерно опишу паттерн ECS, и свою реализацию  в Flame Steel Engine Game Toolkit. Паттерн Entity Component System (Сущность, Компонент, Система) используется в играх, в т.ч. на движке Unity. Каждый объект в игре представляет из себя Сущность, которая заполнена Компонентами.  Зачем это нужно если есть ООП?
Затем чтобы менять свойства, поведение, отображение объектов прямо во время выполнения игры. Такие вещи не встречаются в прикладных приложениях реального мира, динамика изменения параметров, свойств объектов, отображения, звучания, присущи больше играм, чем бухгалтерскому ПО.


Бананы мы не проходили

Допустим у нас в игре есть класс банан. И геймдизайнер захотел чтобы бананы можно было использовать как оружие. Допустим в текущей архитектуре бананы никак не связаны с оружием. Делать банан оружием? Делать все предметы оружием?
ECS предлагает решение данной насущной проблемы – все объекты в игре должны состоять из компонентов. Раньше банан был классом Banana, теперь мы сделаем его, и все остальные объекты, классом Entity (Сущность), добавим им компоненты. Допустим банан теперь состоит из компонентов:

  1. Компонент позиции (координаты в игровом мире – x, y, z)
  2. Компонент поворота (координаты x, y, z)
  3. Компонент калорийности банана (главному герою нельзя сильно толстеть)
  4. Компонент картинки банана

Теперь мы добавляем для всех бананов новый компонент, который является флагом того что его можно использовать как оружие – Компонент оружия. Теперь когда игровая Система видит что игрок подошел к банану, она проверяет наличие компонента оружия у банана, и если он есть, то вооружает игрока бананом.
В моей игре Flame Steel Call Of The Death Mask, паттерн ECS используется везде. Объекты состоят из компонентов, компоненты сами могут содержать компоненты. Вообще разделение объект < – > компонент в моей реализации отсутствует, но это даже плюс.

screenshot_2016-09-24_14-33-43

Дробовик на данном скриншоте является компонентом игрока и в то же время второй дробовик просто висит на игровой карте как обычный объект.
На данном скриншоте работают две Системы – отрисовщик сцены и отрисовщик интерфейса. Отрисовщик сцены работает с компонентом изображения дробовика на карте, отрисовщик интерфейса с компонентом изображения дробовика в руках игрока.

Ссылки по теме:
https://habrahabr.ru/post/197920/
https://www.youtube.com/watch?v=NTWSeQtHZ9M

Теряя себя

“Нельзя стать мастером всего” – меня всегда смешили подобные фразы. В эту ловушку специализации попадают все – пользователи, программисты, начальники, заказчики. “Хочу как у Microsoft/Apple/Google”, “Почему нам просто не сделать русский айфон?”, “Почему здесь не как в ворде/убере/фотошопе?” – эти фразы слышал любой, причастный хоть как-то к ИТ. Эти фразы, повторенные из уст разных людей, звучат еще смешнее.

Я спрошу тебя читатель – зачем тебе еще один Ворд? Зачем тебе еще один убер? Зачем тебе еще один фотошоп? Зачем тебе нужно чтобы “было как в айфоне”?
Почему ты привязываешь себя к интерфейсам и подходу только одной компании? Почему ты навешиваешь на себя ярлык любителя только продуктов Apple/Google/Microsoft? Почему ты не можешь открыть свой разум альтернативным подходам к решению задач, почему не хочешь быть более продуктивным?

Очень многим пользователям Microsoft не понравилось как компания решила что всем необходимо обновиться до Windows 10. Люди ругают неудобные интерфейсы айфона, крэши системы при обновлении, изменения в дизайне которые им не нужны, но все равно продолжают пользоваться ими, потому что так привыкли, и иметь “айфон” это статусно в современном обществе.

Иногда создается впечатление, что если Microsoft/Apple/Google попросят отдать собственных детей в обмен на продолжение работы с их продуктами, то из-за высокой привязанности к этим продуктам, люди запросто отдадут своих чад.

Не будь ими, не привязывайся к одному продукту, посмотри альтернативные варианты. Однажды мне предложили разработать систему для риелторов, с интерфейсом на Microsoft Excel, также были предложения разработать систему “интерактивной доски на Microsoft PowerPoint”. На вопрос почему именно Microsoft мне ответили что “так привыкли”, на вопрос есть ли лицензионное ПО от Microsoft в данных компаниях мне ответили уклончиво, что мол если нужно будет – то купят.

Читатель, я призываю тебя изучить грани ИТ мира, хотя-бы обзорно. Если ты пользуешься всю жизнь только Microsoft Windows, попробуй Apple OS X, или Linux. Если ты пользуешься только iPhone, попробуй хотя-бы неделю попользоваться Android последней версии. В момент когда ты переходишь на сторону только одной компании, закрываясь от продуктов других, в этот момент ты теряешь себя. Себя, как человека который может сам решать чего хочет, как человека который может выбирать наиболее удобный и продуктивный инструмент для решения конкретной задачи.

Программисты только одной платформы – еще одна головная боль лично для меня, как я считаю, для ИТ-индустрии в целом. Разработчики которые делают приложения с экспортом только в *.doc или только в *.pdf, разработчики которые привязываются к только одной устаревшей коммерческой БД (например IBM Informix, или боже упаси Firebird), только к одному типу железа (все эти нерабочие программы для x86 на андроид), я конечно понимаю что вы “привыкли”, но ребята пора меняться.

В своей работе очень часто пользуюсь не популярными, но очень удобными инструментами. Один из примеров – необходимо было уменьшить разрешение и сжать около 100 фотографий, для быстрой загрузки по 3G и выводе на iPad. В тот день я услышал одну из наиболее типичных фраз  – “Нам придется все фотографии вручную в *фотошопе* переводить к нужному виду”. Смешной она мне показалась т.к. я представил себе человека который будет вручную, как раб божий, все эти 100 фотографий переделывать в фотошопе, или пытаться автоматизировать через встроенный механизм. Дело здесь именно в том что человек настолько привязан к фотошопу, что даже не подозревал о наличии бесплатного, открытого набора инструментов как ImageMagick. ImageMagick позволяет делать с векторными и растровыми изображениями очень много вещей, в том числе идеально подошел для 5-минутного решения задачи со 100 картинками.

Будьте мастером всего, изучайте, пробуйте, не становитесь рабом конкретной корпорации.