@alexandre108

Концепция создания бота в многопользовательской игре на WebSocket?

Предположим есть браузеры в виде клиентов и есть сервер. И общаются они между собой с помощью WebSocket.

Как правило, простой вариант координации в таком варианте, выглядит в виде пачки ифов и с стороны клиента, и с стороны сервера. Пример клиента:

ws = new WebSocket("wss://site.com:8888/"); 
ws.onopen = function() {
   ws.send({'e':"new", 'x':lPlayer.getX(), 'y':lPlayer.getY()});
};
ws.onmessage = function(event){
   var msg = event.data;
   if(msg.e == 'new'){
       var newPlayer = new Player(scene, {x,y,z}, msg.x, msg.y);
       newPlayer.id = msg.id;
       newPlayer.init(msg.id);
       remotePlayers.push(newPlayer);    
  }else if(msg.e == 'move' ){
       var movePlayer = playerById(msg.id);
       movePlayer.set(msg.x, msg.y, msg.z);
  }else if(msg.e == 'rotate' ){
      var rotPlayer = playerById(msg.id);
      rotPlayer.setA(msg.a);
      rotPlayer.setB(msg.b);
  } 
}

Пример сервера:

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({port: 8888});
wss.on('connection', function(ws) {
    clients[max_id] = ws;
    this.id = max_id;
    ws.on('message', function(e) {
       if(e.e == 'new'){
            var p = new Player(max_id, e.x, e.y);
            this.player = p;
            clients.send_all({'e':"new", 'id':p.id, 'x':p.x(), 'y':p.y,'z':p.z});
            players.push(p);
      }else if (e.e == 'move') {
            var p = this.player;
            p.set(e.x, e.y, e.z);
            clients.send_all({'e':"move", 'id':p.id, 'x':p.getX(), 'y':p.getY(), 'z':p.getZ(), 'msg':'move'})
       }

Ну и во всем этом самый важный нюанс в том что какая либо активность игрока исходит всегда от клиента, от которого сокетами посылается сообщение серверу, а потом уже сервером транслируется всем остальным игрокам для координации.

А активность бота всегда должен продуцировать сервер и транслировать всем остальным. И вот на этом как раз основная дилема. Пока что приходит в голову идея что нужно прописать в каждую активность игроков то есть на каждый if (e.e == 'move') или на каждыйif (e.e == 'shot') какое то действие бота.

Это наверно может выглядеть как то так:

}else if (e.e == 'move') {
      var p = this.player;
      p.set(e.x, e.y, e.z);
      clients.send_all({'e':"move", 'id':p.id, 'x':p.x, 'y':p.y, 'z':p.z})

      var bot = this.player.bot;
      clients.send_all({'e':"move", 'id':bot.id, 'x':bot.x, 'y':bot.y, 'z':bot.z})
}

Но дальше на этом фантазия заканчивается. Вопрос в том как лучше организовать перемещения бота и в архитектуре игры?
  • Вопрос задан
  • 924 просмотра
Пригласить эксперта
Ответы на вопрос 2
@nirvimel
Смешивать логику сервера и логику бота - архитектурно неправильно. В зависимости от типа игры бот может быть:
1. Для однопользовательской - бот может быть отдельным модулем/классом. При запуске игры сервер запускает всех необходимых ботов, передает им ссылку на себя, а дальше они действуют как клиенты, подписываются на оповещения о событиях на сервере, в обработчике этих событий отрабатывают свою логику и отдают команды серверу через тот же клиентский интерфейс. Сервер может знать "своих", чтобы не путать с живым клиентом, но завязывать на этом слишком много логики на сервере не стоит.
2. Для MMO - бот отдельный процесс ОС (может даже на другой машине), он запускается независимо и его падение не затрагивает сервер. Специальный планировщик следит за ботами и перезапускает тех, которые упали по вине кривых скриптов. Ботов можно доверить писать индусам, но сервер должен быть непотопляемым, поэтому нужно стремиться вынести за его пределы как можно больше кода.
Ответ написан
hahenty
@hahenty
('•')
Можно даже развить идею разделения объектов: Игра, Игрок.
Объект "игрок" оперирует соединением с пользователями, сам реализует обмен между сервером и клиентом и отвечает на запросы объекта "Игра". В объекте "Игра", по идее, не надо прописывать какие-либо сокеты, для "игры" есть только игроки, которые могут как-то изменять и реагировать на изменения состояния своими методами.
Можно описать объект "Бот", у которого будут все те же методы и свойства, как у "игрока", но при этом внутри не будет никаких веб-сокетов.
То есть, "Игра" дергает методы своих подключившихся игроков, но "Игре" не важно, бот это или человек. В коде объекта "игра" не должно быть упоминаний про веб-сокеты.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы