Обновление большого количества объектов в реальном времени
| |
TonyForge | Дата: Суббота, 11 Июля 2015, 12:27 | Сообщение # 1 |
частый гость
Сейчас нет на сайте
| Всем привет!
Делаю реалтаймовый космосим (3D, только сингл, платформа PC). Игровая вселенная разбита на секторы (каждый сектор как отдельная локация-кубик, с планетами, станциями и кораблями). Вот такие возможности хочется реализовать для кораблей: - взаимодействие со станциями (посадка/взлет, выполнение некоторого алгоритма на станции, к примеру покупка оборудования, груза) - взаимодействие между кораблями (навигация через steering behaviors, без поиска путей, выполнение некоторого не очень сложного алгоритма имитирующего ИИ, к примеру выбор врагов/друзей, атаковать или преследовать врагов, защищать друзей) - переход кораблей между секторами (хочется, чтобы корабли могли последовать за игроком или летать с грузом на планеты в соседних секторах и т.п.)
При этом сама игра в реальном времени, но когда игрок переходит между секторами можно выполнять любое количество операций (все равно игрок будет смотреть экран загрузки), но пока игрок внутри сектора летает происходящее в других секторах на паузу нельзя поставить (по крайней мере очень не хочется).
Проверил, уже 500 кораблей только с навигацией через steering behaviors и без отрисовки моделей сильно просаживают FPS (неиграбельно). Т.е. в лучшем случае в реальном времени я при текущем подходе смогу обновлять всего пару сотен кораблей на весь игровой мир. Вроде маловато.
Собственно вопрос: как в таком случае быть с производительностью игры? Может у кого-то есть какие-то идеи по организации процесса обновления объектов?
Пока у меня только одна мысль появилась: Ограничить количество кораблей на один сектор (штук 10-20) и обновлять корабли лимитированными порциями распределяя вычисления по времени. А именно: чтобы в секторе игрока обновлялись все корабли за один кадр, в соседних секторах уже за два кадра, в еще более удаленных уже за 3 кадра и так далее. Чем дальше сектор от игрока, тем сильнее размазывать во времени обновление кораблей. Получится что-то вроде замедления времени в удаленных секторах. При этом при переходе игрока в соседний сектор синхронизировать весь мир (до обновить нужное количество раз все корабли в мире, т.к. во время загрузки как я выше уже писал можно сколько угодно вычислений сделать).
Еще был вариант вообще оставить только синхронизацию мира во время перехода игрока между секторами (т.е. не обновлять соседние сектора в реальном времени, а только синхронизировать в момент перехода). Но тогда как быть с кораблями которые должны между секторами летать, они получается не смогут прилететь, пока игрок не покинет текущий сектор и не перейдет в другой.
Сообщение отредактировал TonyForge - Суббота, 11 Июля 2015, 12:31 |
|
| |
MR_Borg | Дата: Суббота, 11 Июля 2015, 12:42 | Сообщение # 2 |
участник
Сейчас нет на сайте
| Может как вариант для кораблей, которые находятся в других секторах упростить навигацию. Ну допустим корабль прилетел в сектор, ему надо сесть на планету. До планеты лететь 100 км. Считаем за сколько времени корабль окажется в точке посадки и просто переносим его туда. Режим боя: Как я делаю(у меня правда все в 2д). У каждого корабля сделать параметр его "крутости". По разности этих параметров + шанс рандома определяется победитель.
Изучаю C++ попутно пишу игру.
|
|
| |
Tymonr | Дата: Суббота, 11 Июля 2015, 12:54 | Сообщение # 3 |
With OpenSource forever♥
Сейчас нет на сайте
| Цитата TonyForge ( ) Пока у меня только одна мысль появилась: Ограничить количество кораблей на один сектор (штук 10-20) и обновлять корабли лимитированными порциями распределяя вычисления по времени. А именно: чтобы в секторе игрока обновлялись все корабли за один кадр, в соседних секторах уже за два кадра, в еще более удаленных уже за 3 кадра и так далее. Чем дальше сектор от игрока, тем сильнее размазывать во времени обновление кораблей. Получится что-то вроде замедления времени в удаленных секторах. При этом при переходе игрока в соседний сектор синхронизировать весь мир (до обновить нужное количество раз все корабли в мире, т.к. во время загрузки как я выше уже писал можно сколько угодно вычислений сделать). Я примерно так же тайловую карту обновляю. Только я отталкиваясь от ФПС делаю - в случае, если проседает, берутся меньшие и менее важные порции. Т.е. автоматически регулируется кол-во нужных итераций за секунду, подводя все к производительности данной машины
Если вы решили обратиться к нам за помощью, не становитесь в позицию неудачника. И не ведите себя как неудачник. Лучший способ получить быстрый и чуткий ответ, - спрашивать как победитель — спрашивать как человек умный, уверенный в себе и знающий, которому просто понадобилась помощь при решении одной конкретной проблемы. Как правильно задавать вопросы в технических форумах
|
|
| |
TonyForge | Дата: Суббота, 11 Июля 2015, 12:55 | Сообщение # 4 |
частый гость
Сейчас нет на сайте
| MR_Borg, Тоже думал про вариант с упрощением вычислений, но не понятно как быть с событиями, которые мы пропускаем перебрасывая корабль сразу в точку назначения (по пути на него могли напасть пираты, которые как раз летели тем же курсом и в заранее неизвестной точке пересеклись с кораблем и сбили его, это просто как пример. Учитывая, что корабли у меня выбирают курс с помощью steering behaviors, то заранее предсказать куда корабль свернет сложно, слишком много факторов нужно учитывать, к примеру ему по пути мог попасться астероид и облетая его он наткнулся на пиратов, не предсказуемо). Насчет схватки согласен, если поймать сам момент начала боя, то можно все упростить в этом месте до простого броска кубика и подсчета очков. Так если подумать, то поймать момент тоже не очень просто (см. выше про характер движения кораблей в мире).
Т.е. понятно, что упрощение нужно, но слишком сильно упрощать не хочется.
Сообщение отредактировал TonyForge - Суббота, 11 Июля 2015, 12:58 |
|
| |
MR_Borg | Дата: Суббота, 11 Июля 2015, 12:59 | Сообщение # 5 |
участник
Сейчас нет на сайте
| TonyForge, Ну вот смотри, летит корабль от станции к станции либо еще куда то, ведь ты его не видишь, какая разница как он пролетит от а до б, пусть даже сквозь астероид. Пусть движется материальная точка по простому уравнению прямой. Пересечение курсов пирата и корабля можно будет же легко найти.
Изучаю C++ попутно пишу игру.
|
|
| |
Gudleifr | Дата: Суббота, 11 Июля 2015, 13:08 | Сообщение # 6 |
почти ветеран
Сейчас нет на сайте
| Проблема чисто startrek-овская. И решалась еще в те времена очень просто. Не упрощением, а полным забиванием на отслеживание никому не интересных событий. Ведь наша цель - организовать интересное окружение игрока. Допустим, запустив наш честный симулятор 100500, раз мы получим что в 80% случаев в новом секторе мы встретим более 50 врагов, а в 20% - меньше. Так зачем убеждаться в этом каждый раз? Так и поставим: вошел в сектор - увидел с вероятностью 80%... Тем более, что играть может быть интересно с другими вероятностями и их легко можно будет поменять. Не надо себя тешить мыслью, что честно считая, мы сможем получить более интересные ситуации. Ничего того, что мы не предусмотрели не появится само по себе.
Быдлокодеры любят повторять: "логика, убивающая мозг",- когда их пытаются заставить программировать.
|
|
| |
TonyForge | Дата: Суббота, 11 Июля 2015, 13:39 | Сообщение # 7 |
частый гость
Сейчас нет на сайте
| Gudleifr, Ты навел меня на хорошую мысль. Надо разбить корабли на два 2 класса: NPC и мобы. - Мобы это полиция, пираты, локальные грузовые корабли, вобщем все, что живет внутри сектора никогда его не покидая. И их как раз создавать при загрузке сектора и удалять при выгрузке, а количество их в секторе определять некоторыми параметрами (вероятностями или пропорциями). - NPC это уже полноценные виртуальные игроки, которые могут перемещаться между секторами, садиться и взлетать со станций, покупать себе охрану и т.д. Главное, что их число жестко ограничено и не слишком большое.
MR_Borg, Думаю я тебя понял, из твоей идеи тоже можно кое что почерпнуть. Думаю для NPC можно будет сделать два разных алгоритма обновления: 1 - когда NPC и игрок находятся в одном секторе, тут все без упрощений 2 - когда NPC в одном из соседних секторов и вот тут как раз обновлять его по упрощенной модели, как ты предлагаешь, т.е. порезать по максимуму все не нужные вычисления поворотов, огибания препятствий и т.п. Рассматривать их как материальные точки с радиусом и простой логикой взаимодействия. При касании радиусов разных кораблей вычислять сразу итог касания (коснулся с пиратом - вычислился результат схватки, коснулся станции - вычислился результат пребывания на станции и т.д.)
Вообще ребята спасибо, думаю если все это вместе реализовать + в случае сохранения тормозов обновлять не каждый кадр, то должно получиться.
Сообщение отредактировал TonyForge - Суббота, 11 Июля 2015, 13:40 |
|
| |
TLT | Дата: Суббота, 11 Июля 2015, 15:18 | Сообщение # 8 |
Сейчас нет на сайте
| Не вижу смысла обновлять данные частотой в 1 фрейм. Это же 30-60 раз в секунду. Что ж вы делаете…
Достаточно будет сделать обновление по схеме Loading – постепенно.
Дао, выраженное словами, не есть истинное Дао.
|
|
| |
TonyForge | Дата: Суббота, 11 Июля 2015, 17:43 | Сообщение # 9 |
частый гость
Сейчас нет на сайте
| Цитата Достаточно будет сделать обновление по схеме Loading – постепенно. Расскажи поподробнее, пожалуйста, или ссылочку дай где почитать, что за схема такая.
Вообще в моем представлении если не каждый фрейм обновлять, то это: - либо обновлять все, но с меньшей частотой кадров и тогда для отрисовки нужна интерполяция (на больших скоростях объекты могут себя нестабильно вести, пролетать сквозь препятствия и т.п., надо подбирать шаг). - либо обновлять объекты не все разом, а порциями и тогда чем больше объектов, тем сильнее будет заметна задержка в реакции на события в игре. Вроде тоже не хорошо.
Все-таки 30 раз в секунду обновлять все объекты - это некий залог стабильности и предсказуемости работы игры.
|
|
| |
|