Как я должен обрабатывать постоянство в Java MUD?OptimisticLockException обработка - PullRequest
3 голосов
/ 22 марта 2010

Я заново внедряю старую игру BBS MUD на Java с разрешения оригинальных разработчиков. В настоящее время я использую Java EE 6 с фасадами EJB Session для игровой логики и JPA для постоянства. Основной причиной, по которой я выбрал сессионные бины, является JTA.

У меня больше опыта работы с веб-приложениями, в которых, если вы получаете исключение OptimisticLockException, вы просто перехватываете его и сообщаете пользователю, что его данные устарели, и ему нужно повторно подать заявку / повторно подать заявку. Отвечать «повторить попытку» все время в многопользовательской игре - ужасный опыт. Учитывая, что я ожидаю, что несколько человек будут атаковать одного монстра во время боя, я думаю, что вероятность исключения OptimisticLockException будет высокой.

Код моего представления, представляющий интерфейс командной строки telnet, является клиентом EJB. Должен ли я перехватывать исключения PersistenceExceptions и TransactionRolledbackLocalExceptions и просто повторять попытку? Как вы решаете, когда остановиться?

Стоит ли переходить на пессимистическую блокировку?

Сохраняется ли после каждой команды пользователя перебор? Должен ли я загружать весь мир в оперативную память и выводить состояние каждые пару минут?

Делаю ли я свой фасадный сеанс синглтоном EJB 3.1, который будет функционировать как дроссельная точка и, следовательно, избавит от необходимости делать какой-либо тип блокировки JPA? EJB 3.1 синглтоны функционируют как дизайн для нескольких читателей / писателей (вы аннотируете методы как читатели и писатели).

В принципе, каков наилучший API-интерфейс для разработки и сохранения Java-данных для одновременных изменений данных в приложении, где недопустимо представлять пользователю запросы на повторную отправку / повтор?

Ответы [ 2 ]

4 голосов
/ 01 апреля 2010

Я не могу не чувствовать, что вы чрезмерно усложняете то, что должно быть простой проблемой.

Коммерческие и успешные ММО часто используют такой подход:

Every few minutes or after a significant action:
    copy the player data
    pass the player data to a background thread

In the background thread:
    write each piece of player data to the database

Не существует «одновременных» изменений данных, поскольку каждый игрок сохраняет свои собственные данные в разные строки базы данных. (В некоторых случаях это буквально одна строка - несколько коммерческих игр просто хранят данные игрока как Blob против идентификатора пользователя.) Иногда данные немного устаревшие, но это неважно. Это будет проблемой только в случае сбоя сервера, потому что в противном случае вы в конечном итоге получите текущее состояние в БД. Мы говорим не о межбанковских кредитных переводах.

Что касается игр MUD и BBS, их алгоритм был бы еще проще:

Every few minutes or after a significant action:
    For each property in the player object:
        write a property to the player's file

Опять же, здесь нет разногласий, потому что у каждого игрока есть свой файл.

Сохранение после каждой пользовательской команды действительно излишним, если ваша игра не очень монетизирована, и есть риск, что люди подадут на вас иск, если они потеряют +3 Axe of Awesome из-за сбоя сервера.

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

Что касается «одновременного» доступа к тому же монстру, как в вашем примере, это не имеет значения. Если у вас есть один процесс, монстр должен быть в оперативной памяти. Ваш единственный процесс определяет, кто может ударить монстра и в каком порядке. Это не работа для вашего уровня постоянства. Управляйте игровой логикой в ​​игре и сохраняйте результаты.

1 голос
/ 22 марта 2010

Если я правильно помню, многие классические MUD действительно загружали весь мир в RAM и периодически выводили состояние. Конечно, мои воспоминания со дня, когда размер процесса в 16 МБ считался ужасающим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...