• SiteAnalyzer, технический и SEO-анализ сайтов

Геодата минигайд

  • Автор темы Автор темы yayaya
  • Дата начала Дата начала

yayaya

Ефрейтор
Команда форума
Модератор
Копи паст автор не я.

Геодата - это инструмент, который позволяет проконтролировать некоторые действия клиента (а именно - передвижение и взаимодействие с другими объектами с точки зрения геометрического положения в пространстве). NPC проходящие сквозь стены, игроки стреляющие через препятствия - всего этого можно избежать если использовать геодату. Именно она позволяет серверу проверить может ли обьект пройти от точки А в точку Б; можно ли как-то возамодействовать с обьектом в точке Б, находясь в точке А; может ли вас видеть обьект находящийся в точке Б и многое другое.
Сервер геодаты может быть как встроенным (большинство сборок Aion) так и внешним, который можно запустить на отдельном компьютере.
Как вы наверное заметили, существует два формата геодаты: *.map и *.geo, которые я и попробую описать в данном обзоре.

*.map

Как уже многие знают, карта высот в клиенте предаставлена файлами land_map.h32 которые находятся в архивах \Levels\[имя карты]\Level.pak
На картинке внизу этот показана часть файла в шестнадцатиричном редакторе. Для сравнения - показана структура .map-файла


Весь файл представляет собой непрерывный перечень: [высота в точке1][высота в точке2][высота в точке3]...[высота в точкеN] Если карта у нас размером 1536х1536 то этот файл содержит 2359296 записей (занимает примерно 7Мб).
Каждая запись это всего три байта:

struct PointData{
shot Aptitude;
//высота (2 байта)
byte Special; //служебный байт (1 байт)
}

На картинке внизу показана структура .map файла, видно что она почти такая же, отсутствует лишь служебный байт и байты "развернуты" (было [B0 11] стало [11 B0])

struct PointData{
shot Aptitude;
//высота (2 байта)
}

Для перевода .h32 файлов в .map можно воспользоваться либо уже готовыми утилитами (Aion Geodata Tools) , либо написать самому, благо это недолго.

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


*.geo

Кроме земли в игровом мире существуют деревья, камни, и прочие "препятствия". Формат .geo можно предствить как расширение .map . Он описывает как "землю", так и внутриигровые объекты. Также вроме файлов карт (210010000.geo, 400000000.geo и т.д) включает файл meshs.geo в котором и описываются обьекты.
Структура формата немного сложнее:

UDP: Флаг геодаты 0 - геодаты земли нет, 1 - есть земля. Насколько я понимаю это для удобства, чтобы не заполнять файл .geo нулями.
Имя обьекта - это ссылка на обьект в папках игры (Levels\common\Mesh_Meshes_XXX.pak)

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

Однако без meshs-файла геодата бесполезна, поскольку хотя и содержит информацию об объектах на карте, в ней нет самих моделей.

meshs - файл, как уже было сказано описывает игровые модели и является основным файлом геодаты.


Представление моделей в этом файле - самое простое: имя модели, число вершин, список вершин в формате {x,y,z}, число полигонов, список индексов (ID вершин образующих полигон). Считывая все эти данные, геосервер строит пространственное отображение игрового мира, по сути воссоздает такой же игровой клиент. Поэтому и требует большой объем памяти и вычислительных ресурсов.

Файл meshs.geo строится на основе файла brush.lst из levels.pak и содержит ссылки на игровые модели (UDP: Формат brush.lst - разбирайте сами, он там не сложный))
). Однако, одна игровая модель может содержать несколько подмоделей, например модель - дерева обычно состоит из трех частей: ствол, крона и collision (геодата). Да, большинство игровых моделей уже содержат в себе данные которые можно использовапть в качестве геодаты. Основная проблема - как из модели вытащить нужную часть )).

Можно использовать несколько подходов:
-) Пихать в геодату все модели подряд. Быстро, легко, парсер пишется буквально за пару часов, но громозко. Файл занимает очень много времени и содержит кучу ненужных данных которые будут сказываться на производительности
-) Просматривать каждую модель вручную и доставать из нее нужный обьект. Эффективно, но чертовски медленно (бездна например состоит из более чем 2000 моделей).
-) Полуавтоматический вариант. Компьютер просматривает модель, если находит обьект "collision" - записывает его в геодату, если нет - пропускает файл. Пропущенные файлы в последствии обрабатываются вручную. Тоже медленно, но это пожалуй лучший вариант.


Из этого мини-обзора можно сделать следующие выводы:
1) Геодата в формате .map - бесполезна, мобы все равно будут ходить сквозь препятствия.
2) Файл h32 для бездны - пустой, т.к. в бездне нет уровня земли (и не только в бездне кстати).
3) Бесполезно просить геодату для определенной карты ("ну подарите мне геодату для абисса"), т.к. файл .geo без meshs - также бесполезен.
4) Создание геодаты - тяжкий труд.


P.S. Кусок кода программы на Delphi для перевода h32 в формат geo (кода обьектов тут нет, только земля, но нужен хоть 1 обьект иначе сервер будет вылетать с ошибкой!!!)
 
Geodata (heights and meshes)

GeoData is used to determines correct Z-Position by using Collision Detection Formulas .

It's like a tiny Physics Engine which used on modern games.

When two rectangle collides each other, an event has been occurred using a simple mathematics formula, and the programmer makes correct decision based on it for ex. Killing Enemies, Shooting Targets, ...

Formula Credits: @Nepster

Код:
/**
* Check if two rectangles collide
* x_1, y_1, width_1, and height_1 define the boundaries of the first rectangle
* x_2, y_2, width_2, and height_2 define the boundaries of the second rectangle
*/
boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1, float x_2, float y_2, float width_2, float height_2)
{
  return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
}

bounds.gif _ coords300.png _ triangleIntesect.gif

Скопипастил маленько, источник.
 
Последнее редактирование:
не в курсе кстати где объекты хранятся в клиенте ( деревья , кусты и тд)?
 
не в курсе кстати где объекты хранятся в клиенте ( деревья , кусты и тд)?
Эту статейку не смотрел? Может в папке levels хранятся.
xobotyi написал(а):
в папке levels все .pak файлы содержат в себе .h32 файл
Сейчас нет клиента, чтобы взглянуть на эти файлы, так что это только предположение.
 
Ребят, такое дело. Сразу скажу,что не особо силен в серверах,знания на уровне "разархивировать jar, просмотреть .class файл - ничего не понять"
Установил сервер AION 4.6 GER Portable. там сборка. все с бд портативной,все компилилось само из исходников,в итоге запускается,работает. НПЦ пробегали через стены, понял,что отключена геодата. Включил,распаковал из архива GEO.rar файлики. теперь нцп бегут к стене,и отагриваются,но не оббегают её. не ищут маршрута. если стоять близко к стене,то бьют через нее. Пытался почитать NpcMoveController.java, думал, может там не хватает алогритма обхода препятствий или построения маршрута. Насколько понял, Все двигается во время боя командой NpcMoveController.MoveToObject В общем. куда копать? местами сравнивал с 4.9 на github. Вроде все идентично.
Серв понравился,но проблема с нпц не радует(

Может кто то знает,где-то что-то не включено? ведь проблема примитивная(
 
Нужно переписать двигатель геодаты так что бы он понимал что моб должен обойти, нужно добавить в геодату то, что моб будет оббегать, кусты там, деревья. если есть бабло купить у alex он есть на этом форуме. хотя решения на этом не заканчиваются. Есть немного статей по гуглу как это все работает. Нужно читать и пробовать, такие вещи готовыми и доведенными до ума редко попадают в шару
 
К примеру сейчас моб заходя в стену отагривается, посмотреть где это происходит, тоесть он же распознал что это препядствие, логично подумать что по точкам на карте он сможет его обойти расчитав меньшую дистанцию к краю препядствия, это только бредни сумасшедшего;)
 
Да уж, информации по этому вообще как то не нашел,видимо все англоязычное,на русском вообще поиск никуда не ведет :с А логически не вышло догадаться, как он эти препятствия видит, как вообще алгоритм движения происходит при атаке., в самих файлах там есть и CollisionDetection.и куча всего. ну,думаю,если бы все было так просто,то какой нибудь программист уже написал бы с десяток строк для этого. Значит с моим уровнем не прокатит) А покупать не вариант,серв поставил просто побегать,внешечки посмотреть) но хотелось хоть чет до ума довести.
 
Просто все рассуждают так же как и вы, а тот кому это действительно важно давео имеют решение, например легенда
 
Да,но у легенды есть куда и зачем двигаться) там наверное уже четверть кода перелопачена ихней командой. Но и там не все так удачно,как хотелось бы.
А тут понятное дело,бесплатный движок,бесплатная разработка, Но..раз кто-то написал все это,думаю в его же интересах доводить до ума проект. Версии ведь обновляются. 4.9 уже есть от Aion Lighting.

Но вернемся к нашей теме, я там встречал проверку,кажется на координату Z. Чтобы НПЦ при движении не отрывались от пола. А если попытаться методом копипаста и немного фантазии сделать такую же проверку на Х и У?... правда не понятно,как тогда будет двигаться моб. Нужно конечно учесть,что моб не должен двигаться только по стенам,как пьяный.
 
Я тут подметил такую фигню, что для sumon заклинателя стены являются вполне реальными, вот ищу в чем прикол, он же является таким же мобом, но для него геодата и стена непроходимы. Кто то может вскапнуть в эту сторону?! Давайте вместе.
 
Вообщем поразкинув остатком извилен, пришел к заключению, что моб распознает препятствие если дать ему это делать, тоесть отагривается двигаясь в сторону плеера но уже не заходит в препядствие, отагр происходит до стены, а не в самой стене, теперь нужно сделать сам обход стены.
Хоть что то сдвинулось, все молчат как рыбы;) втихаря там правят и молчат;)
 
Вообщем поразкинув остатком извилен, пришел к заключению, что моб распознает препятствие если дать ему это делать, тоесть отагривается двигаясь в сторону плеера но уже не заходит в препядствие, отагр происходит до стены, а не в самой стене, теперь нужно сделать сам обход стены.
Хоть что то сдвинулось, все молчат как рыбы;) втихаря там правят и молчат;)

Да не в отагре дело , отагр нормально реализуем . А вот обход препятствий тут совсем другое . Хотя , сказать что на офе 100% обходит тоже будет лукавством . Сам лично наблюдал и застрявания и проходы сквозь препятствия . Но обходят (если всё таки обходить начинают) они всё таки шикарно на офе .
Но опять же , там вся дата читается своим алгоритмом , а не так как у нас распакованная и спарсеная . Да и под гео там естественно отдельный сервер .
На легенде до 3.0 мне кажется слитый птс стоял , даже при рестарте сначала мобы и нпц пропадали все .
Но это так , размышления . Что нибудь наподобии npc_walker придумать бы тут o_O
 
Как то меня это тронуло;) нашел кучу алгоритмов обхода препятствия вот эксперементирую, самый простой как я понял "A*" Астар или а звездочка
 
Как то меня это тронуло;) нашел кучу алгоритмов обхода препятствия вот эксперементирую, самый простой как я понял "A*" Астар или а звездочка

Все проще. Задействуем пройденные координаты таргета. к примеру сетку с радиусом агра моба. Кидаем его на пройденный x, y, z таргета (к примеру сохраненный в мапе). Делаем список до предела радиуса агра и выбираем координату из списка которую прошел таргет, вклиниваем моба. Видос потом сниму покажу как это работает)).
 
Попытался сделать обход через поиск ближайшего к игроку места, из которого нпс видит этого самого игрока. Получилось очень даже презентабельно по сравнению с обычным отагром.
просто надо допилить отагр при атаке (на видосе из-за него отагриваются) и добавить немного запаса по координатам, а то край препятствия цепляет иногда(нпс вверх подпрыгивает)
 
  • Like
Реакции: WeRn
Попытался сделать обход через поиск ближайшего к игроку места, из которого нпс видит этого самого игрока. Получилось очень даже презентабельно по сравнению с обычным отагром.
просто надо допилить отагр при атаке (на видосе из-за него отагриваются) и добавить немного запаса по координатам, а то край препятствия цепляет иногда(нпс вверх подпрыгивает)
Очень даже неплохо, можно работать и будет годнота.
 
Если кому интересно - получилась такая шняга


Легко реализовать, но плохо работает с низкими/узкими препятствиями
 
Назад
Сверху