Модульный объект: как это работает в «Аллодах Онлайн»
DESCRIPTION
Докладчик: Михаил Казаков, глава команды Астрала на проекте «Аллоды Онлайн».TRANSCRIPT
![Page 1: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/1.jpg)
www.mail.ru
Михаил Казаков Старший программист, команда «Аллодов Онлайн»
Модульный объект: как это работает в Аллодах
![Page 2: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/2.jpg)
www.mail.ru 2
Организация игровых объектов
???
![Page 3: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/3.jpg)
www.mail.ru 3
Игровой объект с позиции ООП
• Жесткая иерархия объектов• Разрабатывается на этапе планирования игры• Легко поддерживается– Логика внутри объекта– Зависимости видны явно
• Если дизайн не менять
• А если менять?
![Page 4: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/4.jpg)
www.mail.ru 4
• В конечном итоге– Class UberObject– Весь код в одном классе– Непонятно, где чья логика– Каша из зависимостей– Трудно что-то добавить
• Не доводите до такого { }Игровой объект с позиции ООП
class MyObject
![Page 5: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/5.jpg)
www.mail.ru 5
Объекты в «Аллодах»
Entity
Creature Device Ship
Avatar Mob
![Page 6: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/6.jpg)
www.mail.ru 6
Объекты в «Аллодах»
Entity
Creature Device Ship
Avatar Mob
AstralMob
![Page 7: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/7.jpg)
www.mail.ru 7
Объект «Астральный моб»
• Мозг• Сотворение заклинаний
• Атака кораблей• Перемещение
• Он же Ктулха
![Page 8: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/8.jpg)
www.mail.ru 8
Объект «Обломки корабля»
• Движение• Стрельба• Перевозка игроков• Взаимодействие с ктулхами
• Подбор кораблями
![Page 9: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/9.jpg)
www.mail.ru 9
Модульный объект Аллодов
• Общий контейнер– Хранит компоненты, предоставляющие интерфейсы– Отображение интерфейсов в их компоненты– Интерфейс указывается явно при добавлении– Умеет get() и put()– Больше ничего не умеет
• Интерфейс компонент– Сам по себе не умеет ничего
![Page 10: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/10.jpg)
www.mail.ru 10
Модульный объект Аллодов
• Создание объекта
Bunch createMyObject() {final Bunch myObj = new Bunch();final Health health = new Health(100);myObj.addPart(Health.class, health);return myObj;
}
![Page 11: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/11.jpg)
www.mail.ru 11
Модульный объект Аллодов
• Получение определенной запчасти
void doSomething(@NotNull Bunch obj) {final Health health
= obj.getPart(Health.class);health.consume(30);
}
![Page 12: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/12.jpg)
www.mail.ru 12
Модульный объект Аллодов
• Не спрашивайте, что это за объект• Спросите, умеет ли он то, что вам нужно?
if(myObj instanceof MyClass) {// Wrong way :(
}if(myObj.getPart(MyPart.class)!=null) {
// Right way :)}
![Page 13: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/13.jpg)
www.mail.ru 13
Объекты можно собирать «на лету»
void assemble(@NotNull Bunch myObj) {myObj.addPart(Health.class, new Health(100));myObj.addPart(IFFOwner.class, new IFFOwner());<...>
}
• Таких функций может быть много
![Page 14: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/14.jpg)
www.mail.ru 14
Знаем только про то, что нам нужно
void affect(@NotNull Bunch myObj) {final Mortal mortal = myObj.getPart(Mortal.class);final Health health = myObj.getPart(Health.class);if(health.getLevel() < 50.f)
mortal.die();}
• Нет зависимостей на тип объекта• Нет зависимостей, полученных «в нагрузку»
![Page 15: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/15.jpg)
www.mail.ru 15
Взаимодействия - между компонентами
Object
Part
Part
Part
Object
Part
Part
Part
Part
![Page 16: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/16.jpg)
www.mail.ru 16
void transform(@NotNull Bunch myObj) {myObj.removePart(CannonTargetInfo.class);
myObj.removePart(ShipCollisionHandler.class);myObj.addPart(WreckCollisionHandler.class,
new WreckCollisionhandler());}
• Можно заменять реализации интерфейсов
Можно изменять поведение объекта
![Page 17: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/17.jpg)
www.mail.ru 17
void mortalTest () {final Mortal mortal = new Mortal();Assert.assertFalse(mortal.isDead());mortal.die();Assert.assertTrue(mortal.isDead());
}• Объект целиком создавать не обязательно• Можно и более сложные функциональные тесты
Легко тестировать
![Page 18: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/18.jpg)
www.mail.ru 18
Куда положить редко нужную логику
Объект
Объект
ОбъектОбъект
Объект
Объект
Объект
Объект
![Page 19: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/19.jpg)
www.mail.ru 19
Куда положить редко нужную логику
Какое-то событие
Объект
Объект
ОбъектОбъект
Объект
Объект
Объект
Объект
![Page 20: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/20.jpg)
www.mail.ru 20
• В стандартном подходеvoid someInternalProcessing() {<...>if(eventActive)
doExtraLogic();<...>
}void itHappened(@NotNull MyObj obj) {obj.eventActive = true;
}
Куда положить редко нужную логику
![Page 21: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/21.jpg)
www.mail.ru 21
• В модульном подходеclass ExtraLogic implements BunchPart {void doExtraLogic() {
// Extra logic goes here}
}
void itHappened(@NotNull Bunch obj) {obj.addPart(ExtraLogic.class, new ExtraLogic());
}
Куда положить редко нужную логику
![Page 22: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/22.jpg)
www.mail.ru 22
Пример использования «редкой логики»
Обновление позиции
Сканирование
![Page 23: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/23.jpg)
www.mail.ru 23
Можно применять и для других целей
Сервис
Сервис
Сервис
Компонент
Компонент
Компонент
![Page 24: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/24.jpg)
www.mail.ru 24
Недостатки
![Page 25: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/25.jpg)
www.mail.ru 25
void process(@NotNull Bunch obj) {if(obj.getPart(RequiredPart.class) == null) {
// И что теперь делать?}<...>
}
• Например, заклинания, наносящие урон по площади
Подходит нам объект или нет?
![Page 26: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/26.jpg)
www.mail.ru 26
void assebleObj(@NotNull Bunch obj) {obj.addPart(Part1.class, new Part1());obj.addPart(Part2.class, new Part2());obj.addPart(Part3.class, new Part3());
}
• Мы точно ничего не забыли?• Эти запчасти между собой не конфликтуют?
Заработает ли собранное?
![Page 27: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/27.jpg)
www.mail.ru 27
• В классическом подходе
class MyObj {@NotNullpublic MyPart part = new MyPart();
}
void process(@NotNull MyObj obj) {obj.part.doSomething();
}
Нет проверок @NotNull
![Page 28: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/28.jpg)
www.mail.ru 28
• В модульном подходеBunch assembleMyObj() {final Bunch myObj = new Bunch();myObj.addPart(MyPart.class, new MyPart());return myObj;
}void process(@NotNull Bunch obj) {final MyPart part = obj.getPart(MyPart.class);if(part == null) return; /* Never happens */part.doSomething();
}
Нет проверок @NotNull
![Page 29: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/29.jpg)
www.mail.ru 29
<spell><targetImpacts>
<Item type = “ImpactKill” /></targetImpacts>
</spell>• Что нужно от цели воздействию ImpactKill?– Нужно ли ему здоровье?– А что будет, если его нет?
В данных тоже есть проблемы
![Page 30: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/30.jpg)
www.mail.ru 30
Как это улучшить?Несколько мыслей
![Page 31: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/31.jpg)
www.mail.ru 31
<ObjectProfile name=“Смертный”><persistentParts>
<Item type=“Mortal” /><Item type=“Health” />
</persistentParts></ObjectProfile>• Возможно, стоит уметь использовать несколько
профилей в одном объекте
Нужна типизация объектов
![Page 32: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/32.jpg)
www.mail.ru 32
<spell><casterProfile name=“” /><targetProfile name=“Смертный” />
</spell>
• Воздействия должны декларировать свои требования
А также операций с ними
![Page 33: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/33.jpg)
www.mail.ru 33
@ObjProfile(name = “Смертный”)class MyObj extends Bunch {void assempleParts() {
<...> }
}
• Что-то вроде типизации в легкой форме.
Не обязательно в данных
![Page 34: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/34.jpg)
www.mail.ru 34
• Не забывайте про дизайнеров!• Как что работает должно быть понятно из редакторов– Разумеется, они должны быть
• Лучше – из самих данных– Текстовый редактор F4
• Билд-система тоже полезна
Нужна поддержка в данных
![Page 35: Модульный объект: как это работает в «Аллодах Онлайн»](https://reader038.vdocuments.net/reader038/viewer/2022102902/557f9be4d8b42ad60b8b45cc/html5/thumbnails/35.jpg)
Михаил КазаковСтарший программист,
Команда «Аллодов Онлайн»[email protected]
СПАСИБО!
www.mail.ru
Mail.RuРазработчик игр и сервисов №1Крупнейший работодатель в отрасли
Работайте у нас[email protected]://corp.mail.ru/career/vacancies/voronezh