Growing Crystals vol 5. сервер и место случайности в игровом процессе

Здравствуйте друзья! Сегодня 6й день и 5й выпуск саги о разработке игры Growing Crystals, сегодня нам предстоит более глубокая проработка серверной части на PHP, реализация перемещения персонажа и немного игрового процесса, а также предстоит ответить на философский вопрос: random or not random?

Прежде чем двинуться вперед, позволю себе небольшое отступление о технологиях клиента. Увлекаясь чтением статей на тему Canvas и частично сталкиваясь с WebGL не отрицаю что возможен переход и на WebGL, поскольку технология уже прошла первичную и, можно сказать, вторичную обкатку и существует большое количество готовых библиотек, способных существенно сократить время разработки. Вполне возможно, что после первого релиза всерьез рассмотрим эту технологию применительно к Growing Crystals.
Немного ссылок: примеры на threejs.org библиотеке WebGL с лучшими отзывами, voxeljs.com/ классный набор инструментов и готовых открытых проектов. Вопрос когда Mojang заменят JRE клиент https://minecraft.net/classic/play на JS+Canvas? Вопрос времени, хотя для меня это казалось вопросом нескольких месяцев уже в 2011. Хабрапост о WebGL для Microsoft Store.

Итак, приступая к реализации серверной части на PHP, я задался очень серьезным и важным вопросом: использовать ли какой-нибудь фреймворк и если использовать, то для чего и как? Поскольку на сервере всё равно придётся хранить данные авторизаций пользователей, статистику для лучшего понимания баланса игры и много всего прочего, то, фреймворк безусловно нужен! Однако я теряюсь в догадках какой именно фреймворк взять за основу и почему? Буду признателен за комментарии.

WebSocket

Компонент WebSocket является частью интерфейса HTML5 для подключения веб-страницы к сокету сервера. Он предоставляет событийно-управляемое соединение между браузером и сервером. Это означает, что браузер может не опрашивать сервер для получения новой порции данных в каждый следующий период времени. Сервер сам посылает обновленные данные серверу. Это дает возможность участникам игры на HTML5 взаимодействовать друг с другом в реальном времени. Когда один игрок что-то делает и потом посылает серверу некоторые данные о своих действиях, сервер, в свою очередь, отправляет для всех остальных подключенных пользователей событие, чтобы те приняли данные о действиях первого пользователя. Благодаря этому можно впоследствии реализовать полноценный мультиплеер в игре Growing Crystals, к нему мы приступим не ранее первого релиза. Итого, у нас есть полное понимание технологической части, за некоторыми малыми исключениями. К тому же все советы товарища о которых я писал в vol 4. выполнены.

Оставшиеся советы (зачёркнуто):

  • В данном проекте необходима реализация протокола обмена при котором сервер может обратиться к клиенту
  • Нужно прочесть опыт других в habrahabr

PHP начало

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

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

Наброски игрового процесса
Клиент Сервер
Кнопка play нажата! Скрываем приглашение в игру на клиенте и отправляем запрос на сервер.
  • Сессия()
  • Если сессия не пустая и игровой процесс уже шел, значит удалить данные о существующем игровом процессе.
  • Загрузить 0е состояние, новую игру (инициализация карты, игрока и др.).
  • Отправить все данные клиенту
Игрок делает ход! Отправляем данные о совершенном ходе на сервер, предварительно проверив простую корректность, например чтобы игрок не пошел в стену.
  • Сессия()
  • Если сессия пустая и игрового процесса нет, ответ с ошибкой.
  • Математическая обработка и проверка возможности хода игрока.
  • Отправить клиенту новое игровое состояние.
Клиент автоматически: сколько кристаллов набежало?
  • Сессия()
  • Если сессия пустая и игрового процесса нет, ответ с ошибкой.
  • Математическая обработка, расчёт.
  • Отправить клиенту новое игровое состояние.

Для того, чтобы начать обрабатывать подобные сообщения необходимо чуть-чуть довести игровой интерфейс. Для начала увеличим видимую область до 10×10, добавим вывод имени игрока и имеющихся у него кристаллов, немного отладочной информации (координаты X, Y, версию клиента, версию сервера, время последнего обновления).

После нескольких часов в Photoshop получился вот такой вот UI v.0.01

UI v.0.01

UI v.0.01

Попытаемся его реализовать средствами canvas. Как это получилось или не получилось, вы увидите ниже.

Немного порисовав на бумажке, родилась следующая структура классов для программирования в PHP.

base.class.php
element_class — Элемент игрового мира. Кирпичик.
map_class (*element_class) — Карта игрового мира, которая включает внутри себя большое колличество экземпляров класса элемент.

player.class.php
player_class — Класс игрока.

communicator.class.php
communicator_class — Класс отвечающий за связь с клиентом.

game.class.php
game_class (1map_class, 1player_class, 1communicator_class) — Главный класс, отвечающий за работу игры.

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

Предупреждение, элементы управления не учитывают адаптивную верстку: лучше смотреть на экране не менее 700 px в ширину.


HTML5 CANVAS

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

Текущий функционал сервера:

  • Инициализация
  • Деинициализация
  • Загрузка/сохранение игрового поля
  • Создание и ведение сессии игрока
  • Анализ перемещений игрока по игровому полю
  • Анализ допустимых ходов игрока
  • Передача данных в JSON

Адрес сервера, можно покидать GET запросы типа ?act=start, ?act=n, ?act=s и другие.

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

Игровой процесс random or not random

Первое задание которое необходимо реализовать в игре — исключительно сбор кристаллов! Задача игрока собрать ограниченное количество кристаллов (например 1000) как можно быстрее. Естественно, игроку должно что-то не давать это сделать, также у игрока должна быть возможность это сделать несколькими способами и оптимальное решение не должно быть очевидно. Понятно, что для реализации помех нам нужно вводить либо злодеев, либо непрочность и ненадёжность производящего или хранящего кристаллы оборудования. Но весь вопрос заключается в том, как определить время когда придёт злодей? Напрашивается ответ, что оно должно лежать в определенном диапазоне и быть случайным, но тогда получается, что разные игроки выполняя это задание ставятся в неравные условия, что делает игру от части на везение! А этого хотелось бы избежать. В статьях о разработке RPG-игр часто можно встретить использование случайных чисел, например “шанс критического урона”, даже простая атака часто рассчитывается с использованием вероятности зависящей от переменной ловкости, т.е. чем выше ловкость, тем больше вероятность сильного удара. В проекте Growing Crystals достаточно мест, где напрашивается использование вероятностной модели, например, в автоматическом сборщике кристаллов, я даже писал об этом в абзаце частота появления кристаллов описывая что появление желтого кристалла это случайность и большая удача. Но ведь моменты использующие генератор случайных чисел (далее random) ставят игроков в неравные условия, хотя это и допустимо и присутствует в большинстве игр не ухудшая а улучшая играбельность и азарт, например в покере, в монополии, даже в карточном дураке. Но мне хотелось бы попробовать соблюсти принцип одинаковые условия для всех, создав своеобразные шахматы, где всё зависит только от навыков и стратегии играющего. Завтра предрелизный день, и весь день будет посвящен разработке первого игрового задания, посмотрим как удастся уйти от random и чем усложнить достижение цели в 1000 кристаллов.

Идеи в goods box

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

Идеи в trash box

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

Краткий итог: Начата реализация серверной логики на чистом PHP. Реализована сессия и перемещение игрока по игровому полю. Начата работа по созданию первого игрового сценария и выпуску первого релиза игры.

Сводка

Начало: 25 апреля 2014 года.
Команда: 1 человек.
Израсходовано: 34 + 12 = 46 чч.
Средняя производительность: 46/6 = 7,(6) чч/день

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

30/100

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

5/100

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

15/100

Веб-клиент

15/100

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

20/100

ИТОГО

85/500

Продолжение: Growing Crystals vol 6. день до релиза