Saber Interactive · тестовое задание
От структуры данных до битвы с боссом
Одно тестовое задание и три способа думать: точный алгоритм, анализ игровых систем и рабочий прототип на Unity.
Готово к ревьюТри задания. Одна инженерная история.
Короткое вступление, связывающее алгоритм, анализ игр и прототип битвы с боссом.
Готово к ревью
Первое задание · Алгоритм
Сериализация и десериализация двусвязного списка с произвольными ссылками Rand за линейное время.
Задача
Нужно сохранить и восстановить двусвязный список с полями Prev, Next, Rand и Data — без изменения класса узла и без стандартного сериализатора.
Особенность задачи — Rand: ссылка может указывать на любой узел, включая текущий, или быть null. Поэтому недостаточно сохранить только значения и порядок элементов: нужно сохранить структуру связей.
Подход
Я заменяю ссылки на узлы стабильными индексами. Сначала прохожу список по Next и строю таблицу «объект → индекс»:
номер | данные | индекс Rand
------+--------+------------
0 | A | 2
1 | B | 0
2 | C | -1
В сериализованной записи остаются данные узла и индекс цели Rand. Значение -1 означает null.
При десериализации сначала создаются все узлы. Затем восстанавливаются Prev и Next, а вторым проходом Rand разрешается по индексам. Поэтому прямые, обратные и циклические ссылки обрабатываются одной схемой.
Результат
После восстановления получается новый полноценный двусвязный список с исходными данными и связями. Исходная модель узла не меняется, а формат записи остаётся детерминированным.
Сложность — O(n) по времени и O(n) по дополнительной памяти. Это оптимально: каждый узел нужно хотя бы один раз прочитать и записать.
Код решения
Ниже — компактная версия основной реализации.
public sealed class ListNode
{
public string Data;
public ListNode Prev;
public ListNode Next;
public ListNode Rand;
public ListNode(string data) => Data = data;
}
public static string Serialize(ListNode head)
{
var nodes = CollectNodes(head);
var indices = new Dictionary<ListNode, int>();
for (var i = 0; i < nodes.Count; i++)
indices[nodes[i]] = i;
var output = new StringBuilder();
output.Append("LL1|").Append(nodes.Count).Append('\\n');
foreach (var node in nodes)
{
var randIndex = node.Rand == null ? -1 : indices[node.Rand];
output.Append(Encode(node.Data)).Append('|')
.Append(randIndex).Append('\\n');
}
return output.ToString();
}
public static ListNode Deserialize(string payload)
{
var lines = payload.Replace("\\r", string.Empty).Split('\\n');
var count = int.Parse(lines[0].Split('|')[1]);
var nodes = new List<ListNode>(count);
var randIndices = new int[count];
// Сначала создаём все узлы.
for (var i = 0; i < count; i++)
{
var fields = lines[i + 1].Split('|');
randIndices[i] = int.Parse(fields[1]);
nodes.Add(new ListNode(Decode(fields[0])));
}
// Затем восстанавливаем все связи.
for (var i = 0; i < nodes.Count; i++)
{
nodes[i].Prev = i == 0 ? null : nodes[i - 1];
nodes[i].Next = i == nodes.Count - 1 ? null : nodes[i + 1];
nodes[i].Rand = randIndices[i] < 0 ? null : nodes[randIndices[i]];
}
return nodes.Count == 0 ? null : nodes[0];
}
Готово к ревью
Второе · Анализ игр
Три игры, которые сильнее всего впечатлили меня за последние несколько лет, и выводы о связи механик, решений игрока и обратной связи.
Выбор
Я выбрал Wuchang: Fallen Feathers, Diablo IV и ARC Raiders, потому что именно эти игры сильнее всего впечатлили меня за последние несколько лет. Мне важно сравнить не жанры, а разные способы связывать механики: бой и исследование, сюжет и развитие персонажа, информацию и риск.
Я провёл около 30 часов в Wuchang, около 80 часов в Diablo IV за два-три сезона и около 120 часов в ARC Raiders. Поэтому дальше я говорю не о пересказе обзоров, а о собственном игровом опыте. В каждом примере меня интересует, какое решение принимает игрок, как игра объясняет последствия и почему возникающий цикл хочется повторять.
Игровой контекст
Для контекста оставляю два скриншота из моего публичного Steam-профиля: это быстрый визуальный маркер того, что перед нами разбор игр, в которые я действительно регулярно играю.


Wuchang: Fallen Feathers
Бой как чтение ситуации
Меня зацепили мрачная азиатская стилистика, сочетание оружия и способностей и исследование скрытых уголков мира. Но главное впечатление оставила боёвка: для меня это не обмен ударами, а танец, в котором игрок и противник по очереди пытаются перехватить темп.
Игрок выбирает, что делать дальше: исследовать мир, искать ресурсы, подготовиться или идти к боссу. В бою нужно понять намерение противника, выбрать момент для ответа и собрать комбинацию. Когда тайминги становятся понятнее, я получаю меньше урона и реже погибаю не только из-за усиления персонажа, а потому что лучше читаю ситуацию. Это хороший пример обратной связи через результат действия.
Босс-сражения особенно хорошо показывают этот принцип: сначала приходится ошибаться, затем распознавать закономерности, и после этого бой становится спокойнее. Ограничение тоже заметно: боссы, насколько я заметил, почти не меняют поведение в ответ на действия игрока. Это упущенная возможность сделать бой более живым.
Что я забираю в Avatar of Nature
Я забираю масштаб босса, связанного с ареной, и последовательность «сигнал → решение → ответ». При этом поведение босса не должно быть полностью неизменным: его дистанция, повторяющиеся действия игрока или попытка добраться до слабой точки могут влиять на следующий выбор. Это пока гипотеза, которую нужно проверять в прототипе.
Diablo IV
Сюжет, мир и понятная сборка
Я играл за призывателя: начал со скелетов, затем попробовал сборку с заклинаниями. Больше всего меня зацепили сюжет, атмосфера, постановка, музыка и русская озвучка. Кампания постоянно создавала вопрос «что дальше?», поэтому хотелось продолжать.
Сюжетные задания поддерживаются побочными занятиями, регулярными событиями и совместной зачисткой локаций. Игрок почти всегда может выбрать понятную следующую цель, а мир не заканчивается вместе с основной линией. Развитие персонажа связывает навыки и экипировку со стилем игры: здесь достаточно глубины для выбора, но не требуется разбираться в огромном дереве возможностей.
Слабое место этого решения — прогрессия постепенно превращается в повторяемый цикл: улучшить экипировку, пройти подземелье и повторить. Для меня это важный урок: доступная система развития должна давать выбор, но ей также нужен следующий смысловой горизонт, иначе рост превращается в рутину.
Что я забираю в Avatar of Nature
Для собственного босса я забираю принцип связного опыта: цель, подача и награда должны поддерживать друг друга. Это не готовая механика из Diablo IV, а направление для прототипа — дать игроку понятную задачу и сохранять интерес между ключевыми моментами боя. Конкретное применение ещё требует проверки.
ARC Raiders
Информация превращается в риск
ARC Raiders стала первой игрой в жанре шутеров с эвакуацией, в которую я играл достаточно долго. Меня зацепили вселенная, исследование, сбор предметов и постоянное напряжение между противниками-роботами и другими игроками.
Главное решение в рейде — понять, что ещё можно успеть сделать и хватит ли ресурсов для следующего столкновения. Игрок читает карту, звуки стрельбы, состояние уже обысканных мест, поведение противников и визуальные сигналы. Игра не даёт готовый ответ, но предоставляет достаточно информации, чтобы оценить риск и решить, продолжать рейд или уходить.
В одном рейде группа противников стреляла по нам с дальней дистанции. Мы развернулись, пошли на сближение и выбили весь отряд. Этот эпизод запомнился тем, что дистанционное преимущество противника стало причиной для контратаки. При среднем времени устранения игрок успевает перегруппироваться, поэтому тактика часто важнее мгновенной реакции.
Ограничение проявляется позже: когда основные направления развития достигнуты, добыча и новые рейды могут начать повторять уже знакомый цикл. Это пока моё наблюдение, а не вывод по статистике аудитории, но оно показывает: сильной основы недостаточно, если опытному игроку нечего осмысленно осваивать дальше.
Что я забираю в Avatar of Nature
Я забираю информационный дизайн и цену решения. В бою с боссом нужно заранее сообщать об угрозе, оставлять время на перегруппировку и награждать правильный выбор, а не только скорость реакции. Это хорошо сочетается со слабой точкой как наградой за понимание поведения босса.
Общий вывод
Во всех трёх играх меня зацепила не сумма механик, а их связь. В Wuchang бой, исследование и подготовка усиливают друг друга. В Diablo IV кампания, занятия и развитие персонажа поддерживают живой мир. В ARC Raiders информация, позиция и риск превращают перестрелку в решение с последствиями.
В Avatar of Nature я хочу проверить тот же принцип в меньшем масштабе: дать игроку сигнал, оставить место для интерпретации, изменить состояние арены и сделать награду понятным следствием его выбора.
Готово к ревью
Третье · Битва с боссом
Avatar of Nature: элементальный босс, построенный вокруг понятных намерений, давления на арену и коротких окон уязвимости.
Задача
Нужно было собрать в Unity небольшой прототип с боссом: придумать атаки, сделать несколько фаз, добавить понятное окно для ответной атаки и показать, как эти элементы работают вместе.
Исходный код доступен в репозитории Avatar of Nature. Готовую Windows-сборку можно скачать из релиза boss-duel-rc-2026-09-21-build2.
Идея сражения
Я проектировал босса, которого нужно не просто расстреливать, а читать. Он остаётся в центре арены, выбирает область давления, предупреждает об атаке и меняет доступное пространство.
намерение босса → сигнал атаки → решение игрока → изменение арены → слабая точка
Основной цикл
Каждая атака содержит цель на арене и ожидаемый результат. Сигнал атаки сообщает, куда направлена угроза. Атаки «Земля» и «Огонь» могут повредить или разрушить сектор; «Ударная волна» проверяет позицию игрока и заставляет его двигаться.
После разрушения сектора открывается короткое окно уязвимости, в котором можно нанести ограниченный урон по слабой точке. Поэтому атака одновременно проверяет позицию, меняет пространство и создаёт возможность для ответа.
Прототип в игре
Видео показывает арену, сигналы атак, изменение пространства и основной игровой цикл.
Две фазы
Первая фаза знакомит с правилами: увидеть сигнал, выбрать позицию, пережить удар и понять связь между изменением арены и окном атаки. Пока слабая точка закрыта, тело босса получает сниженный урон.
Вторая фаза запускается примерно на половине здоровья босса. Атаки выполняются быстрее, сигналы становятся короче, появляется вторая слабая точка и призываемые существа. Это должно проверять уже изученное правило под большим давлением, а не просто уменьшать время реакции.
Читаемость и выбор
Мне важно, чтобы сигнал сообщал не только «сейчас будет урон», но и «какую задачу решает босс». Игрок должен понять, какой сектор оказался под давлением и куда лучше переместиться.
Как это собрано
В этом видео я показываю, как собрал прототип: от правил босса и арены до визуальных сигналов и настройки боя.
Слабая точка как награда
Слабая точка — не вторая шкала здоровья, а короткая награда за правильное решение. Игрок читает угрозу, меняет позицию, переживает изменение арены и получает ограниченное окно для усиленной атаки.
Так в одну последовательность связываются наблюдение, выбор времени, позиционирование и риск. Смысл прототипа — проверить причинно-следственную связь: игрок увидел сигнал, сделал выбор, увидел изменение арены и понял, почему получил окно для атаки.
Арена как ресурс
Арена здесь не просто фон для боя. Каждый сектор — это ресурс, который игрок может сохранить, потерять или сознательно отдать под удар. После разрушения меняется доступный маршрут, поэтому ошибка остаётся в пространстве и влияет на следующие решения.
Это также объясняет, почему вокруг центральной площадки нет обычного цельного пола. Я хотел, чтобы пространство постепенно «заканчивалось» прямо во время encounter: чем дольше игрок просто пережидает атаки, тем меньше у него удобных вариантов. Босс не обязан постоянно ускоряться, чтобы создавать давление — достаточно, что цена плохого позиционирования становится выше.
Разрушение арены создаёт мягкое нарастающее давление: чем дольше игрок пережидает атаки, тем меньше остаётся удобных маршрутов. Так время становится частью решения, а не просто фоном боя.
Что ещё можно улучшить
Это рабочий прототип, собранный вокруг одной идеи: игрок читает угрозу, меняет позицию и получает возможность ответить. Его задача — показать этот цикл в игре и дать основу для дальнейшей полировки.
Дальше я бы улучшал темп фаз, выразительность сигналов и ощущение разрушения арены. Основа уже собрана, а эти улучшения помогут сделать бой ещё понятнее и живее.
Финальное видео
В последнем видео я показываю текущий результат и рассказываю, куда этот прототип можно развивать дальше.