Задать вопрос
@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})
}

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