Terentyev / SmallWorld

Board game "Small world"
6 stars 2 forks source link

Изменения и добавления в протокол #7

Closed pnazarov closed 12 years ago

pnazarov commented 12 years ago

Внесено:

Предложения:

Terentyev commented 12 years ago

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

pnazarov commented 12 years ago

Единственное для чего поле time видимо может пригодиться - это для использования его в качестве значения поля since команды getMessages, но это все равно как то сомнительно

elvslv commented 12 years ago

вы имеете в виду, что время сообщения должно генериться на сервере?

pnazarov commented 12 years ago

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

elvslv commented 12 years ago

хм... а я даже и не помню, зачем в sendmessage у нас время) кому знать? сервер это всегда знает. клиенту, наеврное, неплохо знать

pnazarov commented 12 years ago

клиенту целесообразное запоминать время последнего сообщения, полученного командой getMessages, чем время, когда он сам отправил последнее сообщение.

pnazarov commented 12 years ago

Интересует замечания/предложения/согласия/возражения по поводу других предложенных изменений и дополнений )

elvslv commented 12 years ago

согласна

Terentyev commented 12 years ago
{
  "action": "sendMessage",
  "sid": <sid>,
  "text": "<text>"
}

Как и написано в документации. А вот ответ на эту команду должен быть таким: Success

 { "result": "ok" }

Соответственно команда getMessage принимает вид:

{
  "action": "getMessages",
  "msgNum": <уникальный, порядковый номер последнего сообщения, которое мы получали>
}

Соответсвенно, если мы ещё ни разу не получали сообщения, то передаем msgNum == 0. Но для того, что бы клиенту не загружалась история всех сообщений, которые когда-либо были написаны, правильнее было бы ограничить кол-во возвращаемых сообщений, например, 100 (тоже взято из документации)

Ответы на эту команду: Success

{
  "result": "ok",
  "messages": [
    {
      "userId": <userId>,
      "message": "message",
      "msgNum": <порядковый уникальный номер сообщения>
    }
  ]
}
Terentyev commented 12 years ago
elvslv commented 12 years ago

а я считаю, может быть, кроме getGameState, в которой будет вся информация об игре, может иметь смысл сделать несколько мелких команд типа getVisibleCombinations, getUserState, getRegionState... не утверждаю, что конкретно эти, но все же. потому что результат команды getGameState оч объемный, не уверена, что целесообразно каждый раз все запрашивать, когда можно запросить только, скажем, десятую часть

Terentyev commented 12 years ago

Ты экономишь трафик в момент, когда каналы Интернета растягивают на себе торренты? =) Ладно...

Зачастую игровая команда будет вносить изменения в несколько блоков (например, покупка расы меняет состояние игрока и состояние комбинаций, конец хода -- состояния игры и игрока, применение каких-то способности может менять состояния либо [игрока, регионов] [игрока, другого игрока]), поэтому клиенту придётся делать по несколько запросов подряд.

Если уж сильно хочется экономии трафика, то могу предложить, чтобы сервер выдавал по одному запросу только то, что изменилось. Но для этого надо будет хранить историю изменений состояния всей игры,а выдавать по запросу с какой-то версии (наподобие того, как я говорил про getMessages)

elvslv commented 12 years ago

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

Terentyev commented 12 years ago

Появилась замечательная идея! Чтобы не плодить множество команд получения состояния игры и её составных, можно сделать следующее:

{
  "action": "getGameState",
  "sid": int,
  "fields": [название поля структуры TGameState]
}

В свою очередь TGameState будет иметь какую-то такую структуру:

{
    players: [TPlayer],
    map: TMap,
    regions: [TRegion],
    turNum: int,
    pairs: [TRacePowerPair]
}

Но эта структура ещё в стадии разработки (вроде), так что...

И, Лена, скажи: ты поддерживаешь поправку команд getMessages, sendMessage, getGameList, uploadMap?

elvslv commented 12 years ago

да, меня все устраивает

Terentyev commented 12 years ago

Я так понял, Василий тоже в теме?

elvslv commented 12 years ago

не знаю

pnazarov commented 12 years ago

Так как Вася дал нам права в https://github.com/vkevroletin/web-game-doc предлагаю это обсуждение перенести в тот проект

kevroletin commented 12 years ago

On 10/12/2011 11:14 AM, Pavel Nazarov wrote:

Так как Вася дал нам права в https://github.com/vkevroletin/web-game-doc предлагаю это обсуждение перенести в тот проект

Мне только пришло сообщение, начиная с того, в теме ли я по поводу того, чтобы не плодить команд в протоколе. Ответ - за. Предыдущие обсуждения прошли мимо меня.

kevroletin commented 12 years ago

Ого, нашёл таки где вы и что обсуждали. Вообще на самом деле тонкий момент. { players: [TPlayer], map: TMap, regions: [TRegion], turNum: int, pairs: [TRacePowerPair] } Вот из этого всё кроме карты, я считаю, надо возвращать одной команды. У игроков же есть свои идентефикаторы, достаточно вернуть массив этих идентефикаторов. Аналогично с картой и парами расса-умение, находящихся на столе. С регионами чуть сложнее. Насколько я понял этот массим описывает на каком регионе стоят какие фишечки? Ну тогда если это не смешивать с описанием карты, то было бы логично вернуть вместе с остальным. будет просто массив, конечно здоровый, но по-хорошему этой командой не надо пользоваться часто(Здесь всплывает вопрос о том, что по-хорошему пользователям необходимо последовательно отсылать все изменения) В этоге я за то чтобы пердевать всё, но для игроков, карт, расс-умениний передавать их id. И добавить команду(ы) для получения игроков, карт, по id или по их уникальному имени типа getUserInfo getMapInfo. Что касается расс и умений - нужно спецефицировать какие есть рассы, какие у них названия, и будем ли мы по аналогии с юзерами и картами вводить какие-то отельные id или хватит просто униклаьного имени.

Вася.

elvslv commented 12 years ago

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

kevroletin commented 12 years ago

Было бы неплохо спросить, что именно непонятно.

То же самое другими словами: я считаю, нужно всё возбращать одной командой. Но не надо при этом каждый раз возвращать полную информацию о пользователях, карте, рассах и умениях, достаточно идентефикаторов и команд, которые по этим идентефикаторам возаращают полную информацию о пользователе, карте и т.д. Кроме того нужно обсудить как нужно отправлять пользователю информацию о ходах других игроков. Почти что достаточно просто несколько раз вернуть то что возаращает getGameState по завершению каких то ключевых моментов в игре - после атаки одного игрока и защиты другого игрока, чтобы можно было красиво нарисовать кто как ходил и кто как защищался. Еще отдельно нужно как то показать, что челс бросил топор, наколдовал и т.д.

О, хотя нет, я не прав по поводу вот этого:

будет просто массив, конечно здоровый, но по-хорошему этой командой не надо пользоваться часто (Здесь всплывает вопрос о том, что по-хорошему пользователям необходимо последовательно отсылать все изменения)

kevroletin commented 12 years ago

И заканчивая расшифровку предудущего сообщения:

Я подумал, что regions, которые возвращает getGameState это то же самое, что и поле regions карты. Разуверь меня и скажи, что информация о карте не дублируется и там только информация о фишечках, находящихся на регионе. Чего в принципе достаточно.

elvslv commented 12 years ago

дублируется. частично. там вся информация, в т.ч и о различных фишечках

kevroletin commented 12 years ago

Ну вот информацию о карте, думаю стоит убрать.

Полностью поддерживаю идею о введении getMapList

Предлагаю добавить еще что то вроде getGameList getGameInfo getMapList getMapInfo getUsersList getUserInfo

Помимо getGameState предлагаю обсудить целесообразность введения и формат getLastChanges - для получения информации о ходах других игроков.

Про сообщение - как я понимаю, в каждой игре свой отдельный чат ? Поддерживаю исключение даты из GetLastMessages. В принципе можно было бы заодно сообщения отсылать getLastChanges - клиент всё равно будет этой командой постоянно стучаться(в той или иной форме мы же всё равно добавим такую команду)

pnazarov commented 12 years ago

Не совсем понятен смысл предложенных команд getUsersList/getUserInfo - какую информацию о игроке они должны возвращать? По расам: Как я понял реализуется 13 классов рас, все кроме (Ghouls), названия такие же как в правилах; вводить какие-то отельные id для рас думаю не стоит достаточно уникального имени.

elvslv commented 12 years ago

Насчет рас согласна с Пашей

kevroletin commented 12 years ago

On 10/13/2011 12:48 PM, Lena Vasilyeva wrote:

Насчет рас согласна с Пашей Значит без id-шников.

On 10/13/2011 12:46 PM, Pavel Nazarov wrote:

Не совсем понятен смысл предложенных команд getUsersList/getUserInfo - какую информацию о игроке они должны возвращать? По расам: Как я понял реализуется 13 классов рас, все кроме (Ghouls), названия такие же как в правилах; вводить какие-то отельные id для рас думаю не стоит достаточно уникального имени.

Ну как я понял, для пользователей тоже будут id-шники, надо будет иметь способ получить имя пользователя по id. Так же можно узнать в какую игру сейчас играет пользователь.

elvslv commented 12 years ago

Значит так, прошу обратить внимание, я обновила доки, особенно обратите внимание на register -- теперь он возвращает id зарегистрированного юзера(очевидный изначальный косяк в протоколе). Сейчас по-любому появится куча недовольных неудобных, плохо продуманным, неэффективным протоколом, так вот -- предлагаю всем недовольным самим менять доки(естетсвенно, после предварительного обсуждения этих изменений со всеми остальными)

kevroletin commented 12 years ago

Выяснился удивительный факт: http://rghost.net/25545551.view В правилах сказано, что после нападения защищающаяся сторона держит фишки в руке и ставит их на стол в конце хода атаковавшего игрока. Такой подход должен несколько ускорить игровой процесс, т.к. http с постоянными опросами сервера вносит задержки, да и в принципе если 3 раза напасть на игрока он будет переставлять фишки лишь один раз. Кроме того это упрощает процесс захвата территорий игрока, т.к. он не укрепляет свои территории после каждой защиты. Логику такая реализация не упростит, т.к. в правилах так же написано, что фишки должны убегать на несмежные территории. Для этого придётся запоминать сколько фишек убежало с какой территории.

Вобщем главный вопрос стоит ли это того, чтобы команда Лена+Лёня+Наташа переписывала свои тесты и поправили код и будут ли они это делать.

elvslv commented 12 years ago

Я согласна, косяк мой, неверно поняла правила. Насчет ускорения игры -- да, скорей всего, сама игра будет идти быстрее. Также согласна с тем, что это сильно влияет на логику игры. НО! Я считаю, что в целом эти правила взаимозаменяемы, т.е. замена одного правила на другое сильно не поменяет равновесие в игре (в одном случае преимущество у атакующего, т.к. он может захватить все территории одного чувака, в другом -- у защищающегося, т.к. он может вовремя свалить куда-нить подальше)) А т.к. каждый игрок будет и атакующим, и защищающимся за игру, т.е. прочувствуюет все плюсы и минусы выбранного правила. Вам по реализации, думаю, будет одинаково(если еще ничего не написано), нам возможно немало придется переделывать. Так вот, если вы все же настаиваете, чтобы мы потратили еще кучу сил на то, чтобы это переделать, ок) Но только чур Вася переделывает протокол и мы уже в соответствии с этим переделываем код и логику.

pnazarov commented 12 years ago

Пара вопросов к Лене:

  1. Ошибка "badSid" Как я понял эта ошибка возвращается если указанный sid не существует; если игрок не в игре, а должен в ней находиться; либо сейчас не его ход в игре, а он ходит. но команды "leaveGame", "setReadinessStatus" возвращает "notInGame" если игрок не в игре. Тогда мы либо возвращаем в этой ситуации "badSid", либо во всех командах добавляем "notInGame" в случае если игрок не в игре. Какой вариант выбираешь? ) И как правильно "badSid" или "badUserSid"? потому что в документации и так и так написано.
  2. getGameState -поле gameState.currentPlayersNum и gameState.map.playersNum не одно и тоже? -что храниться в "tokenBadgeId "? -не кажется тебе лишним хранить gameState.map.regions.inDecline если у нас для региона есть ownerId и tokenBadgeId, а в gameState.players есть declinedTokenBadge.tokenBadgeId? -gameState.players.isReady разве во время игры оно нам нужно? -gameState.players.coins не хотелось бы открыто хранить данные о монетках, вроде бы смысл игры в том, что окружающие не знают сколько их у тебя. -и где в gameState собственно сам массив(ы) с Расами и Специальными умениями
  3. Как определяется очередность ходов игроков и игре?
  4. getGameList
    • games.activePlayer - надо ли знать человеку, который не в игре, это значение?
    • games.state = 3 = GAME_ENDED - предлагаешь хранить даже закончившиеся игры? 5.getGameList games.state и getGameState gameState.state одно и тоже?
pnazarov commented 12 years ago

И вопрос ко всем будем ли мы реализовывать один глобальный чат, как предложил Кленин, потому что это якобы легче, либо сделаем все таки для каждой игры свой чат + 1 чат для игроков, не находящихся в какой либо игре?

elvslv commented 12 years ago
  1. нет, badSid возвращается только если такого сида нет. и должно быть badUserSid, если где-то нет, то переименуем.
  2. -нет, не забывай, игра же может быть не начата, и currentPlayersNum -- количество присоединившихся к ней. а gameState.map.playersNum -- количество игроков из описания карты.

  3. у нас это идентификатор уникального сочетания раса + умение
  4. можно и убрать. ну только если соберетесь убирать, не забудьте протокол поменять
  5. ну вообще-то состояние игры можно запрашивать и когда она еще не начата
  6. повторюсь, это можно сделать и на уровне клиента
  7. имеешь в виду, что можно выбрать? да, сорри, забыла из добавить в документацию. ну там должно быть что-то типа visibleTokenBadges:[{'raceName':, 'specialPowerName': }], возможно имеет смысл еще tokrnBadgeId добавить, но не уверена
  8. по порядку присоединения их к игре. тот, кто создал -- первый
  9. -мож и не надо -мы вроде это на парах обсуждали, да, храним и закончившиеся, просто по умолчанию их не показываем

насчет чата -- предлагаю оставить так, как есть. потом, если захотим, добавим пару запросов, в которых будет указана игра, или тчо-то там еще. проблема что ли.

кстати, насчет ответа на login -- предлагаю возвращать все-таки userId, gameId. Потому что если следовать тому, что вы предалагали, т.е. делать на это отдельный запрос, получается, что если пользователь зашел в игру, разлогинился, потом снова залогинился, нам нужно посылать запрос на информацию о нем. и уже проверено, что как раз еще один запрос -- вот это очень неэффективно. если никто не против, я в login добавляю userId, gameId

pnazarov commented 12 years ago

что то я запутался badSid и badUserSid одна и та же ошибка?

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

elvslv commented 12 years ago

ну т.е. была badSid, стала badUserSid.

хорошо, давайте возвращать только незавершенные.

что насчерт login? и еще бы неплохо было бы возвращать в нем isReady, опять из тех же осоображений. Говорю все по своему опыту написания клиента

pnazarov commented 12 years ago

Согласен пусть login возвращает userId isReady точно не нужно возвращать его можно узнать или из getGameState или getGameList с gameId сложнее, по идеи после команды логин клиент в любом случае должен посылать команду getGameList что бы показать игроку текущие игры, и зная наш userId мы можем по нему определить gameId если он есть.Так что возвращать gameId в команде логин думаю не стоит, но если так будет особо возражать не стану )

elvslv commented 12 years ago

эм. вообще-то у нас getGameList делается и без входа в систему. именно поэтому и нужен gameId и isReady. Да, это избыточно, но смотри: ты заходишь на страницу, у тебя уже подгружен список игр. Зачем его еще раз грузить, если пользователь залогинился? Вот это реально неэффективно. Нам достаточно просто изменить состояние кнопочек Join, Leave. Именно для этого и нужны gameId и isReady. Потом если пользователь захочет, он сам нажмет refresh

pnazarov commented 12 years ago

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

elvslv commented 12 years ago

А что предлагаешь ты? пользователь разлогинился, все, выкидывать его из игры?

pnazarov commented 12 years ago

Если игра не началась то да, это вполне распространенная практика в играх. Потому что у тебя просто нет другого выхода, если он разлогинился и залогинился обратно, ничего страшного возьмет и снова присоединится к этой игре.

elvslv commented 12 years ago

давайте решим, как будет. можно, конечно, сделать так, что если разлогинился, то все, к игре н готов, и из нее вышел. мне так проще. И если повезло залогиниться и присоединиться до того момента, пока не набралось нужное количество человек, то присоединяется, иначе все, поезд ушел. но если он разлогинился во время игры, значит все, играет уже на 1 человека меньше.

elvslv commented 12 years ago

тогда ситуация следующая: пользователь присоединился к игре, нажал готов, закрыл браузер. все? он больше ничего сделать не может? или нам опять же надо делать запрос, играет ли он во что-нить. ладно с разлогинился, это мы можем адекватно обработать. но что будет, если пользователь перегрузил страницу или переоткрыл браузер? нам в любом случае надо знать игры, в которых он участвует, и готов ли он к ним. и следовательно нам надо это проверять после каждого логина. и каждый раз делать getGameList -- неэфективно. поэтому я по-прежнму считаю, что gameId и isReady нужны

pnazarov commented 12 years ago

нет, badSid возвращается только если такого сида нет. и должно быть badUserSid, если где-то нет, то переименуем. А что возвращается если игрок ходит не в свою очередь badStage? И тогда все игровые команды, leaveGame, setReadinessStatus возвращают notInGame если сид на сервере существует но соответствующий ему игрок не находится в этой игре?

elvslv commented 12 years ago

да, badStage - -если не его очередь, если очередь его, но нарушена очередность команд. да, notInGame, если юзер не находится в этой игре

elvslv commented 12 years ago

хотя... не знаю, мож ты это и имел в виду, и я тебя непрально поняла, а может и нет. короче, в loging возвращаем userId

elvslv commented 12 years ago

постараюсь не забыть обновить доки. вы, кстати, обновили доки по send и getMassages?

pnazarov commented 12 years ago

Если игрок разлогинился/вышел из игры во время игры вообще не понятно что делать, т. к. игра по правилам не подразумевает досрочного проигрыша. хорошо если ты считаешь что getGameList каждый раз не эффективно, то isReady можно получить из команды getGameState которую в любом случае нужно посылать если у тебя gameId != null.

elvslv commented 12 years ago

ну нам надо договриться, что делаем, если игрок долго не ходит или вышел во время игры. дмаю, просто всегда пропускать его ход

pnazarov commented 12 years ago

да в login возвращаем userId нет send и getMassages в документации нами не изменялись