Death-Mask Wild Beta

Game Death-Mask goes into the status of a public beta (wild beta)
Reworked the main menu screen of the game, added a view of the blue zone of the techno-labyrinth, with pleasant music in the background.

Next, I plan to rework the gameplay controller, add smooth movement like in old shooters, high-quality 3D models of boxes, weapons, enemies, the ability to move to other levels of the techno-maze not only through portals (elevators, doors, fall through holes in the floor, holes in the walls), add a little variety to the environment of the generated maze. I will also work on the game balance.
Skeletal animation will be added at the polishing stage before release.
You can check public beta here:
http://demensdeum.com/games/deathMask/wildBeta/

0

The Good, the Bad and the Ugly Singleton

In this article I will describe my experience and the experience of my colleagues when working with the Singleton pattern, when working on different (successful and not so successful) projects. I will describe why I personally consider this pattern to not be used anywhere, I will also describe what psychological factors in the team influence the integration of this anti-pattern. Dedicated to all fallen and crippled developers who tried to understand why it all started with one of the team members who brought a cute little puppy, easy to use, does not require special care and knowledge to care for him, and ended up raising the beast, it requires more and more man-hours and eats the man-nerves of users, your money and heavily slow down new features implementation.


Wolf in sheep’s clothing by SarahRichterArt

The story takes place in an alternate universe, all coincidences is purely coincidental…

Pet a cat at home with Cat@Home

Every person sometimes has an overwhelming desire to pet a cat at some point in life. Analysts all over the world predict that the first startup that created the application for the delivery and rental of cats will be extremely popular, in the near future will be bought by Moogle for trillions of dollars. Soon it happens – the guy from Tyumen creates the Cat@Home application, and soon becomes a trillionaire, the Moogle company gets itself a new source of profit, and millions of people who are stressed out can order a cat on home.

Attack of the Clones

Extremely rich dentist from Murmansk Alexey Goloborodko, impressed with the article about Cat@Home from Фorbes, decides that he also wants to be astronomically rich. To achieve this goal, through his friends, he finds a company from Goldfield – Wakeboard DevPops that provides software development services, he orders the development of a Cat@Home clone from them.

The Dream Team

The project is called Fur&Pure, it is assigned to a talented development team of 20 people; further focus on the mobile development group of 5 people. Each team member gets his part of the work, armed with agile and scrum, the team completes the development on time (six months), without bugs, releases the application in the iStore, where it is rated by 100.000 users for 5 stars, many comments about how great the application and excellent service (alternative universe, after all). The cats are ironed, the application is released, everything seems to be going well. However, Moogle is not in a hurry to buy a startup for trillions of dollars, because not only cats, but also dogs have already appeared in Cat@Home.

The dogs bark, but the caravan moves

The owner of the application decides that it’s time to add dogs to the application, applies for an assessment to the company and receives estimation at least six months to add dogs to the application. In fact, the application will be written from scratch again. During this time, Moogle will add snakes, spiders and guinea pigs to the application, and Fur&Pur will only receive dogs.
Why did this happen? The lack of a flexible application architecture is to blame for everything, one of the most common factors is the design pattern anti-pattern Singleton.

Nah, can’t be

In order to order a cat at home, the customer needs to create an request and send it to the office, where they will process it at the office and send the courier with the cat, the courier will already receive payment for the service.
One of the programmers decides to create a class “RequestCat” with the required fields, and brings this class into the global application space through singleton. Why does he do it? To save time (penny saving for half an hour), it’s easier to make an global object than to think about the application architecture and use dependency injection. Then the rest of the developers pick up this global object and couple their classes to it. For example, all the screens themselves refer to the global object “RequestCat” and show the data on the application. As a result, such a monolithic application is being tested and released.
Everything seems to be fine, but suddenly a customer appears with the requirement to add an requests for dogs to the application. The team frantically begins to check how many components in the system will affect this change. At the end of the analysis, it turns out that 60 to 90% of the code needs to be altered to teach the application to take in the global singleton object not only the RequestCat but also the RequestDog, it is already useless to estimate the addition of other animals, it’s already difficult with two.

How to avoid singleton

First, during the requirements gathering phase, clearly indicate the need to create a flexible, extensible application architecture. Secondly, it is necessary to conduct an independent examination of the product code on the side, with the mandatory study of weak points. If you are a developer and you like singletons, then I suggest you think again before it’s too late, otherwise sleepless nights and scorched nerves are 100% guaranteed. If you work with a project, in which there are many singletons, then try to get rid of them as soon as possible, or from the project.
You need to switch from the antipattern of singleton-global objects / variables to dependency injection – the simplest design pattern in which all the necessary data is set to an instance of the class at the initialization stage without further need to be tied to global space.

Documents

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/

0

Gearing Gears

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

0

Black Shaped Box

[English translation may be some day]

К любому разработчику на 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

0

It grows!

[English translation may be some day]

В данной заметке я расскажу о своих злоключениях с умными указателями 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, и полюбить этот инструмент работы с памятью еще больше. Удачного дебага.

0

Games Vision #3

[English translation may be some day]
Третий выпуск непостоянной рубрики об играх 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

0