Неделя 38-40 (июль 2 — июль 4): Все еще сервер.
Так как ничего слишком интересного у меня все еще не происходит, я продолжу объединять недели в длинные статьи. Не уверен, что так удобнее читать, зато масштаб предприятия лучше виден.
Июль 2 — Обучение персонажей
Наверное, самое сложное в механизме рецептов я к этому моменту уже преодолел. Действительно, обучение персонажей выглядит значительно проще крафта: нет дефолтных рецептов, нет очередей, на одного овнера может быть только один рецепт.
Но и тут все оказалось не совсем просто. Дело в том, что у рецептов, отвечающих за обучение, овнером является не постройка, а персонаж. И чтобы найти информацию о постройке, надо сначала найти персонажа. То есть в процесс работы механизма создания рецепта влезает довольно стремный аппендикс.
В общем, я перебрал функцию создания крафта на сервере так, чтобы она, на мой вкус, выглядела более читаемой.
Смешно получилось с результатами этого обучения. Для отображения ролевых параметров у меня есть специальный класс. Когда-то он умел показывать ролевые параметры шмоток и персонажей, но это было будто бы в прошлой жизни уже. Два месяца назад! И вот я прошу вывести этот класс ролевые параметры персонажа, а там по нулям.
Оказалось, что когда я делал генератор персонажей, я не сделал им случайную генерацию ролевых параметров, и их значения действительно были нулевыми. Долго смеялся сам над собой.
Июль 3 — Улучшение построек
Из четырех видов крафта осталась последняя — улучшение построек. И тут было бы все просто, если бы не одно «но».
Улучшение построек очень нежно переживает связи с рестрикшенами. Проблема простая: в интерфейсе нужно показывать только один рецепт, который улучшит постройку текущего уровня до следующего. Но тут возникает один вопрос: показывать ли рецепт если он подходит текущему уровню, но не подходит по каким-то другим параметрам?
С одной стороны, в логике, на сервере, рестрикшены — штука довольно однозначная: если условие выполняется, то действие может быть выполнено. Но с другой стороны, в интерфейсах, все не так однозначно. Нужно ли отображать рецепт, который игрок не может выполнить? При некоторых условиях, нужно. Например чтобы показать игроку, что в игре есть еще недступный ему контент. Это нормальная практика во всех современных играх.
Например есть ферма и рецепт на пшено доступен с первого уровня, а рецепт на кукурузу будет доступен со второго. А еще есть рецепт на коноплю, который будет доступен с третьего уровня. Первые два рецепта видны в интерфейсе. Более того, на второй рецепт даже неплохо было бы взглянуть более подробно — нет никаких препятствий чтобы не позволить посмотреть на список его ингредиентов или даже невыполненных рестрикшенов. Но запустить в работу можно только производство пшена.
А дальше такой вопрос. Например ферма у нас уже второго уровня и нам доступны рецепты и пшена, и кукурузы. Но у кукурузы есть рестрикшен, который требует чтобы у ролевой параметр фермы был больше 150. И что, отображать такой рецепт таким же не доступным как и рецепт еще не доступной конопли? Мне кажется что эти рецепт недоступны по-разному и игрок должен видеть эти отличия еще на этапе иконок. А значит клиент должен различать разные виды недоступности.
И тут довольно простой механизм рестрикшенов начинает обрастать условиями, которые в чистом виде ему совершенно не интересны.
И все было бы хорошо, но на этой неделе вышли Clicker Heroes 2 и Trade Island. Обе игры необычайно интересны и важны для моей настоящей работы, так что я ушел в запой.
Июль 4 — Окончание крафта и инвентарь
К моему счастью разработчики Clicker Heroes 2 решили не делать игру и она довольно быстро перестала отвлекать мое внимание. Trade Island же оказался необычайно крутой и правильной (на мой вкус) игрой, на таких проектах надо учиться и я буду учиться, но по-счастью эта игра не требует слишком дофига внимания (и даже наоборот, учит ставить приоритеты… надо написать на нее обзор).
Тем не менее, я доделал улучшение построек.
- Сделал разные типы результатов условий рестрикшенов — система получилась независимой и необычайно запутанной.
- Сделал отображение невыполненных рестрикшенов в панели ингредиентов.
- Переделал интерфейс окна информации перенеся в него элементы окна крафта. Совсем 1-в-1 не получилось, но единообразие значительно облегчило работу. В окне инфы происходит тот же процесс что и в окне крафта:
- Сначала обрабатывается отображение текущего крафта. Так как кнафт левелапа у постройки может быть только один, тут получилось избавиться от цикла — на самом деле это не важно.
- Потом выбираются доступные рецепты. Так как в каждый момент времени игроку может быть доступно не больше одного рецепта левапа, то я даже панели рецептов не показываю, а единственный доступный рецепт сразу определяю как выбранный.
- Ну а дальше все как в оригинале.
Наконец у меня заработал весь крафт. Я могу строить и улучшать постройки, могу копить ресурсы и крафтить предметы.
Следующий этап: инвентарь и информация о предмете, установка предметов в слоты персонажа, изменение ролевых параметров персонажа, постройки, изменение времени производства крафта и вообще все что с этим связано. По сравнению с тем, что я уже сделал, эта задача совсем простая.
Так до конца недели я успел восстановить отображение информации о предмете. Здесь я напоролся на одну небольшую эстетически-архитектурную проблему.
Вот есть у меня класс артикула. У артикула есть список бонусов. Хоть бонусы артикулов и являются классом, но он находится внутри артикула и соответственно бонус ничего не знает про своего родителя. Из артикула генерируется айтем. У айтема тоже есть список бонусов, который генерируется из списка бонусов артикула. Бонусы айтемов кстати устроены так же — они ничего не знают про свой родительский айтем. При этом бонус айтема содержит всего два поля: айди бонуса артикула и значение бонуса. И тут как бы тупик: как мне из бонуса айтема получить параметры бонуса артикула для расчета итогового значения?
В общем, приходится прокидывать внутрь бонуса айтема ссылки и на родительский айтем, и на библиотеки конфигов и данных игрока. Способ выглядит каким-то костылем, но другие способы до которых я смог додуматься (объединять данные бонусов айтемов и артикулов на уровне айтема) кажутся мне еще более идиотскими. Надо наверное что-нибудь про архитектуры почитать умное.