Growing Crystals vol 8. Улучшаем интерфейс, даём оценку игровому балансу

Прошло 5 полных дней с момента первого релиза. Проект умышленно не рекламировался, т.к. проект находится на стадии начальной разработки и не хотелось бы для широкой аудитории представлять сырой продукт, целью релиза было: убедиться в возможности держать темп разработки проекта и получить первичные отзывы от узкого круга друзей и знакомых. Однако, это сыграло злую шутку — комментариев и даже игр, доведенных до конца, как можно убедиться из таблицы результатов, оказалось крайне недостаточно, поэтому сейчас трудно делать какой-либо статистический анализ даже при наличии логов на стороне сервера. Поэтому, теперь политика привлечения людей к проекту претерпит изменения о которых я хочу сегодня написать. Мне видится следующий план.

1. Исправление интерфейса и всех задач из журнала улучшений.

  • game.class.php:277 non-optimal-solution
  • Подсветка лимитов кристаллов
  • Строительство через события: строительная площадка -> результат
  • Генерация случайного адреса страницы результатов, для обхода кэширования

2. Изменение системы управления, добавление меню строительства, добавление возможности игры на мобильных устройствах (без клавиатуры).

3. Публикация материалов и статей на habrhabr и gamedev. Начиная со статьи, которая будет описывать исправление интерфейса и изменение системы управления.

Приступим…

Исправление интерфейса и всех задач из журнала улучшений

Задачей номер 1 будет оптимизация цикла, исправление ошибки php index out of range (точно не помню что выдавал интерпретатор), но точно знаю что это было связано с тем, что при определении позиции результата игрока в scoreboard цикл while поочередно сравнивал результат игрока с результатами в scoreboard проходя от самого худшего на верх к самому лучшему, и когда результат игрока был наилучшим и занимал наивысшее место (0е место в массиве) попытка выполнения кода $this->scoreboard[$bestplace-1][0] вела к результату $this->scoreboard[0-1][0] что и приводило к выходу за рамки массива.

while($result < $this->scoreboard[$bestplace-1][0] && $bestplace>0){ //Двигаемся пока наш результат лучше
$bestplace--;
}

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

while($result < $this->scoreboard[$bestplace-1][0] && $bestplace>0){ //Двигаемся пока наш результат лучше
$bestplace--;
if($bestplace == 0) break; //Чтобы не обращаться к индексу -1 КОД МОЖЕТ БЫТЬ ИЗБЫТОЧНЫМ ПРОВЕРИТЬ
}

Но, как мне кажется, это не очень изящно. Немного углубившись в php удалось упростить конструкцию. Как оказалось, достаточно было лишь поставить в начало проверку индекса, т.к. условная часть цикла состоит из двух условий (текущий индекс>0) И (результат игрока лучше чем результат с текущим индексом) и при выполнении кода с текущим индексом равным 0, результат условной части цикла будет возвращен в FALSE т.к. FALSE И ЛЮБОЕ ВЫРАЖЕНИЕ, в результате даёт FALSE.

while( $bestplace>0 && $result < $this->scoreboard[$bestplace-1][0]) //Двигаемся пока наш результат лучше
$bestplace--;

Подсветка лимитов в интерфейсе пользователей делается очень простым образом, дополнительно при отрисовке в JavaScript вставляется проверка: если синих кристаллов меньше 3, или меньше чем на 3 от количества синих кристаллов, которые могут поместиться у игрока, подсвечиваем красным цветом. Для красных кристаллов похожее правило, только различие от минимального и максимального значения будет 0, для жёлтых любое количество считается приемлемым.

Добавлена система одиночных событий: реализована очередь событий, которые должны быть исполнены в определенный момент времени. Пока проверка продвижения события по очереди осуществляется по запросу клиента в главном игровом методе process() на сервере, отвечающим за обработку всех игровых событий.
При завершении игры, часто сталкивался с проблемой которая не позволяла обновлять scoreboard, дело в том, что результаты хранятся в виде html страницы со статическим адресом, иногда по запросу html страница передаётся на клиент и браузер может взять её из кеша. Для того, чтобы она не кешировалась на стороне клиента в её адрес необходимо примешивать случайный код после знака “?”.

Помимо этого, лёгкой оптимизации был подвергнут экран игрока. Также все что связано с таблицей результатов (scoreboard) было вынесено в отдельный класс php scoreboard_class. При реализации системы одиночных событий появились трудно отлаживаемые ошибки, пришлось реализовать инструмент логирования (класс console_class) на стороне сервера.

И еще важно, пока не хочется реализовывать супербыструю графику и анимацию считая FPS и загружая процессор на клиенте, пока хочется оставить игру лёгкой.

Рассчитываю на объективную критику и советы относительно игры.

О игровом балансе

Баланс был слегка изменен с целью придания динамики, теперь цель 2000 кристаллов.

Терминология:
b — blue crystals синие кристаллы
r — red crystals красные кристаллы
y — yellow crystals желтые кристаллы
bl, rl,yl — blue/red/yellow crystals limit, количество синих/красных/желтых кристаллов, которое может быть у игрока в распоряжении. Также это обозначение используется для ёмкости сейфов.

ppw — player posible ways, допустимые движения игрока
bs — blue (crystals) speed скорость генерации синих кристаллов

Значения по умолчанию

  • костюм генерирует 1b in sec
  • костюм генерирует 1r per 100sec
  • ёмкость костюма 850b, 2r, 1y
  • кристаллов в наличии по умолчанию 800b

На перемещение на одну клетку авиасёрф расходует 2b.

Сейфы (safes)
Клавиша (код объекта) Стоимость Время на постройку Эффект
Y (s1) 30b 1 sec +100bl
U (s2) 100b 4 sec +300bl
I (s3) 50b,1r 4 sec +200bl +1rl
Сборщики (collectors)
Клавиша (код объекта) Стоимость Время на постройку Эффект
H (c1) 50b 2 sec +1b every 8sec
J (c2) 50b 5 sec +1b every 10sec, время генерации 1r: -1/5
K (c3) 400b 10 sec +1b every 1sec

Идеи в goods box

  • WebSocket
  • После первого релиза завести аккаунт на habrahabr
  • Создать Git для проекта

Идеи в trash box

  • На всех объектах принадлежащих игроку горит дополнительная голубая лампочка;
  • Если у игрока нету топлива, что его авиасёрф перестаёт работать и садится на землю, а в обычном режиме он слегка покачивается в воздухе и работают 4 реактивных двигателя по краям авиасёрфа;
  • Если на складе что-то есть, то у него мигает индикатор;
  • Апгрейды защитных башень;
  • Взрывающиеся при разрушении склады;
  • Артефакт увеличивающий скорость перемещения игрока;
  • Артефакт увеличивающий радиус действия игрока;
  • Предмет, который можно бросить на несколько экранов, чтобы посмотреть что там происходит;
  • Мины;
  • Кузница опыта, производящая специальное вещество, получаемое из сжигания кристаллов и необходимое для получения звания;
  • Звание — это предмет в инвентаре.
  • Объект карты — ограждение;
  • Объекты, расползающиеся по карте;
  • Декоративные мегаобъекты;
  • Наличие сверхдорогих объектов с особыми свойствами;
  • Список друзей, чтобы на них не действовала защитная башня;
  • Общие склады для друзей;
  • Шаринг в социальных сетях;
  • Переход на WebGL.

Управление: WSAD.
Строительство: выбираете объект (YUIHJK), затем WSAD место, куда его разместить.



HTML5 CANVAS

Количество обращений к серверу пока не известно.

Таблица рекордов

Таблица рекордов грузится…

Краткий итог: Были исправлены мелкие недочеты обнаруженные при тестировании релиза r1. Самое главное — принято решение вынести обсуждение проекта на публичные площадки.

Сводка

Начало: 25 апреля 2014 года.
Команда: 1 человек.
Израсходовано: 68 + 8 = 76 чч.
Дней отдыха: 0 + 5 = 5
Средняя производительность: 76/9 = 8,(4) чч/день

Описание игрового процесса

40/100

Расчет баланса

32/100

Игровая графика

25/100

Веб-клиент

20/100

Игровой сервер

32/100

ИТОГО

149/500

Продолжение: Growing Crystals vol 9. Управление браузерной игрой на мобильном устройстве