Подход XMLSocket для многопользовательской карточной игры / игры с домашними животными

Я довольно новичок в многопользовательском дизайне и изо всех сил пытаюсь найти информацию, которая мне нужна для продолжения, в моей синхронной (пошаговой игре, которую нельзя отключить и продолжить позже, как в очаге), пошаговой, пвп "карточной" игре. Я использую AS3 (flash) в качестве своей клиентской стороны и node.js с javascript + mysql для обработки на стороне сервера.

В этой игре карты создаются самими игроками. Важно отметить, что эти "карты" собираются из отдельных строительных блоков (библиотеки SWF-файлов); База данных отслеживает, как эти карты сделаны / собраны. Поскольку на каждого игрока могут приходить сотни уникальных карт, мне нужен хороший способ загружать информацию о них по требованию для сражений в пвп или для целей моддинга / колоды.

Что я сделал до сих пор:

  • Я успешно отправил данные на сервер и отправил данные на флэш-память через XMLSocket.
  • Я успешно собрал одну "карточку" из базы данных.

На какие вопросы мне действительно нужно ответить:

Flash асинхронно загружает контент, поэтому я не уверен, как подойти к созданию нескольких запросов данных для (иногда одновременных) боевых действий, информации о карте или сборке карт (потенциально может быть много карт и блоков для построения карт, поэтому я чувствую, что это будет неэффективно загружать все данные одним запросом). Я могу либо поручить ответственным классам сделать эти вызовы, либо создать класс мессенджера для обработки всех запросов / отключений / повторных подключений / сообщений для всей игры.

  • Что касается подхода с использованием глобального класса мессенджера, я не уверен, как извлечь полностью загруженные данные из мессенджера с помощью вышестоящего кода (as3 продолжает выполнение, даже если данных там нет) или как гарантировать, что запрос относится к соответствующему вызову

    • я мог бы использовать систему запроса идентификатора, чтобы однозначно идентифицировать запрос сокета
    • я мог бы разработать собственную систему управления событиями
    • Я мог бы создать несколько объектов мессенджеров в каждом классе, который мне нужен. <- я склоняюсь к этой опции.
  • На аналогичном замечании, возможно, мне следует обработать запросы к базе данных в объектах карты или предварительно загрузить все данные до начала игры (это ограничило бы меня только запросом карты противника и данных о битве на лету). При подходе объекта "один вызов на карту" я не был уверен, что #requests на карту на игрока сокрушит мой сервер или нет. Node.js очень хорошо масштабируется, но у меня нет сетевых знаний, чтобы понять, будет ли слишком много одновременных запросов к одному порту.

РЕДАКТИРОВАТЬ: я сильно склоняюсь к использованию одноэлементного XMLSocket Wrapper или какого-то расширенного класса для обработки всех сетевых транзакций, так как это кажется мне интуитивно понятным. Я был бы очень признателен за ваши отзывы о том, как лучше всего уведомить мой код о том, что мессенджер получил и проанализировал запрошенное сообщение (поскольку флэш-память продолжит выполнение, даже если данных там нет, мне нужен хороший способ сделать это). Я читал, что использование пользовательских событий не так уж и потрясающе, и есть лучшие способы... но именно так я и подхожу к проблеме.

Например, я могу сделать (псевдокод).

m:Messenger = new Messenger(); //this is my wrapper
m.addEventListener(new CustomEvent(CustomEvent.EVENTSTRING, parseData));
m.sendData(DataObject); //calls 

function parseData(e:CustomEvent) {
    xml(e.data);
}

import flash.net.XMLSocket;
import globals.*;
public class Messenger 
{
    public static var _Socket:XMLSocket; 
    public var xml:XML;

    public function Messenger() 
    {
        _Socket = new XMLSocket(vars._Server, vars._Port);
        _Socket.addEventListener(Event.CONNECT, onConnect);  
        _Socket.addEventListener(IOErrorEvent.IO_ERROR, onError); 
    }

    private function onConnect(evt:Event):void  {  
        trace("Connected");  
        _Socket.removeEventListener(Event.CONNECT, onConnect);  
        _Socket.removeEventListener(IOErrorEvent.IO_ERROR, onError);  

        _Socket.addEventListener(DataEvent.DATA, onDataReceived);
        _Socket.addEventListener(Event.CLOSE, onSocketClose);              
    }  

    private function onDataReceived(evt:DataEvent):void  {  
        //trigger correct event here based on data identifier w/ dispatchEvent(EVENTSTRING);
    }  
}

1 ответ

Решение

О сборке карты - вы должны хранить данные в базе данных, которая не требует пересчета, поэтому, если карта построена из нескольких "строительных блоков", вы можете, например, сохранить последовательность блоков в одной строке базы данных, чтобы когда информация о карте для противника извлекается, вы просто select from player_cards where player_id=... and deck_id=... а затем собрать собранные данные на стороне AS3. Вы определенно не должны помещать эту нагрузку на сервер.

Об асинхронной загрузке - убедитесь, что ваше рукопожатие PVP ждет, пока обе стороны успешно обработают карты как для своей стороны, так и для стороны противника. Вы можете загружать данные асинхронно, но лучше выполнить полную предварительную загрузку, отображая экран "Загрузка бла-бла" в проигрыватель, а затем работать с полученными данными. Да, вы можете сделать несколько запросов к вашему серверу, и да, вы можете подождать, пока все они будут успешными, прежде чем отобразить экран "Начало битвы", в то же время AS3 будет ожидать завершения загрузки. Но, что касается одного или нескольких запросов - я говорю о том, чтобы использовать как можно меньше, потому что каждый добавленный запрос на этапе инициализации - это возможность добавить тысячу или около того запросов к одному серверу, а также потенциальная нагрузка на него. на вашей стороне сервера, что приводит к самозапускаемому DDoS. Убедитесь, что структура вашей базы данных позволяет оптимизировать операции чтения данных прямо на стороне клиента, чтобы ваш сервер не подвергался большой нагрузке при подготовке данных. Но также убедитесь, что дважды проверили, какие клиенты сообщают серверу, так как основным правилом игр клиент-сервер является предположение "клиент всегда лжет".

Поскольку вы планируете выполнять действия игрока серверного процесса в середине битвы, вы можете создавать на сервере временные таблицы (на основе SQL) или объекты состояний (на основе процессов), которые будут содержать текущее состояние игры со ссылками на любые способности карт. и их состояние (в руке, сброшено, в игре, уничтожено и т. д.), поэтому, когда приходит действие от игрока, говорящее "эта карта меняет состояние с А на В", вы можете легко проверить, находится ли эта карта в состоянии А, затем переключите его в состояние B, выполняя любые действия, возникающие в результате этого изменения состояния как на стороне сервера, так и на стороне клиента. Обязательно очистите этот набор данных после окончания битвы. Это требует тщательного планирования вашей серверной стороны, так что ваш игровой движок не будет останавливать сервер при выполнении некоторой последовательности действий, например, из-за избыточных запросов SQL.

О мессенджерах - возможно, вам следует использовать сеансовый подход вместе с аутентификацией по логину / паролю, чтобы сеансы были доступны в качестве ключей, чтобы определить, к какому сражению принадлежит этот пакет данных. Я также считаю, что сторона AS3 должна периодически отправлять запросы извлечения на сервер, которые должны быть быстро проанализированы сервером, а отправленные действия противника / сервера возвращены как можно быстрее, это также гарантирует, что разъединения будут обрабатываться, а повторные соединения разрешены.

В целом, вопрос очень широкий, и могут быть даны только советы, даже не примеры.

Другие вопросы по тегам