Lua, игровое состояние и игровой цикл

  1. Звоните main.lua сценарий при каждом игровом повторении цикла - является этим хороший или плохой дизайн? Как это влияет на производительности (относительно)?

  2. Поддержите игровое состояние от a. Хост-программы C++ или b. из сценариев Lua или c. от обоих и синхронизируют их?

  3. (Предыдущий вопрос по теме: Lua и C++: разделение обязанностей)

    (Я голосую за каждый ответ. Лучший ответ будет принят.)

22
задан Community 23 May 2017 в 12:34
поделиться

7 ответов

Лучшее в lua - это то, что у него легкая виртуальная машина, и после предварительной компиляции фрагментов их запуск в виртуальной машине на самом деле выполняется довольно быстро, но все же не так быстро, как код C ++, и я не думаю, что вызов lua для каждого визуализированного кадра был бы хорошей идеей.

Я бы поместил состояние игры в C ++ и добавил функции в lua, которые могут достигать, и изменить состояние.Подход, основанный на событиях, почти лучше, когда регистрация событий должна выполняться в lua (желательно только в начале игры или в определенных игровых событиях, но не чаще, чем несколько раз в минуту), но фактические события должны запускаться Код C ++. Пользовательские вводы также являются событиями, и они обычно не происходят в каждом кадре (за исключением, может быть, MouseMove, но из-за этого следует использовать осторожно). То, как вы обрабатываете события пользовательского ввода (обрабатываете ли вы все (например, какая клавиша была нажата и т. Д.) В lua, или есть ли, например, отдельные события для каждой клавиши на клавиатуре (в крайнем случае), зависит от игры, в которой вы '') повторная попытка сделать (пошаговая игра может иметь только один обработчик событий для всех событий, в RTS должно быть больше событий, а с FPS следует обращаться осторожно (в основном потому, что перемещение мыши будет происходить каждый кадр)). Разные типы событий у вас есть, тем меньше вам нужно кодировать в lua (что повысит производительность), но тем сложнее становится, если «реальное событие», которое вам нужно обработать, на самом деле запускается более отдельными «событиями уровня программирования» ( что на самом деле может снизить производительность, потому что код lua должен быть более сложным).

В качестве альтернативы, если производительность действительно важна, вы можете улучшить виртуальную машину lua, добавив к ней новые коды операций (я видел, как некоторые компании сделали это, но в основном для того, чтобы сделать декомпиляцию th e скомпилировал фрагменты lua сложнее), что на самом деле несложно.Если у вас есть что-то, что код lua должен делать много раз (например, регистрация событий, запуск событий или изменение состояния игры), вы можете реализовать их в виртуальной машине lua, поэтому вместо нескольких getglobal Коды операций и setglobal будут принимать только один или два (например, вы можете создать код операции SETSTATE с параметром 0-255 и 0-65535, где первый параметр описывает состояние, которое необходимо изменить, а второй описывает новое значение состояния. Конечно, это работает, только если у вас есть максимум 255 событий с максимумом 2 ^ 16 значений, но в некоторых случаях этого может быть достаточно. И тот факт, что для этого требуется только один код операции означает, что код будет работать быстрее). Это также усложнит декомпиляцию, если вы намереваетесь скрыть свой код lua (хотя и не очень для тех, кто знает внутреннюю работу lua). Запуск нескольких кодов операций на кадр (около 30-40 вершин) не сильно повлияет на вашу производительность. Но 30-40 кодов операций в виртуальной машине lua не уйдут далеко, если вам нужно делать действительно сложные вещи (простое if-then-else может занять до 10-20 или более кодов операций в зависимости от выражения).

9
ответ дан 29 November 2019 в 03:46
поделиться

Мое основное правило для lua - или любого языка сценариев в игре -

  • Все, что происходит в каждом кадре: асинхронные события c ++
  • - пользовательский ввод - lua
  • события синхронного игрового движка - lua

По сути, любой код, вызываемый на частоте> 33-100 Гц (в зависимости от частоты кадров), является C ++ Я пытаюсь вызвать скриптовый движок с частотой <10 Гц.

На основе каких-либо реальных показателей? не совсем. но он действительно ставит разделительную черту в дизайне, с четко очерченными задачами C ++ и lua - без предварительного разграничения задачи lua для каждого кадра будут расти до тех пор, пока не начнут тормозить обработку на каждый кадр - и тогда нет четких рекомендаций о том, что сокращать.

25
ответ дан 29 November 2019 в 03:46
поделиться

ИМХО сценарии Lua предназначены для определенного поведения, это определенно ухудшит производительность, если вы вызываете сценарий Lua 60 раз в секунду.

Скрипты Lua часто предназначены для отделения таких вещей, как поведение, и определенных событий от логики вашего игрового движка (графический интерфейс, элементы, диалоги, события игрового движка и т. Д.). Хорошее использование Lua, например, было бы при запуске взрыва (FX частиц), если игровой персонаж куда-то ходит, жесткое кодирование вывода этого события в вашем движке было бы очень уродливым выбором. Хотя было бы лучше сделать запуск движка правильным сценарием, отделив это конкретное поведение от вашего движка.

Я бы порекомендовал попытаться сохранить состояние игры в одной части, вместо того, чтобы повышать уровень сложности синхронизации состояний в двух местах (Lua и Engine), добавить к этому потоки, и в итоге вы получите очень уродливый бардак. Будь проще. (В своих проектах я в основном сохраняю состояние игры на C ++)

Удачи вам в игре!

5
ответ дан 29 November 2019 в 03:46
поделиться

Мне не нравится C ++. Но я люблю игры.

Мой подход может быть немного нетипичным: я делаю все, что могу в Lua, и только абсолютный минимум в C ++. Цикл игры, сущности и т. Д. - все сделано в Lua. У меня даже есть реализация QuadTree на Lua. C ++ обрабатывает графические файлы и файловую систему, а также взаимодействует с внешними библиотеками.

Это не машинное решение, а решение программиста; Я выводю код на Lua намного быстрее, чем на C ++. Поэтому я трачу свои циклы программиста на новые функции, а не на экономию компьютерных циклов. Мои целевые машины (любой ноутбук за последние 3 года) очень легко справляются с таким количеством Lua.

Lua на удивление занимает мало места (посмотрите luaJIT , если вы этого не знаете).

Здесь сказано, что если я когда-нибудь найду узкое место (я еще не нашел), я профилирую игру, чтобы найти медленную часть, и я переведу эту часть на C ++ ... только если я смогу » Я не могу найти способ обойти это с помощью Lua.

5
ответ дан 29 November 2019 в 03:46
поделиться

Большая часть производительности будет потеряна из-за привязки Lua к C ++. Вызов функции на самом деле нужно будет обернуть и снова обернуть, и так обычно пару раз. Чистый код Lua или чистый код C ++ обычно быстрее смешанного кода (для небольших операций).

Сказав это, я лично не видел сильного снижения производительности при запуске Lua-скрипта в каждом кадре .

Обычно сценарии хороши на высоком уровне . Lua использовался в известных играх для ботов ( Quake 3 ) и для пользовательского интерфейса ( World of Warcraft ). Использование микропотоков Lua на высоком уровне очень удобно: сопрограммы могут значительно сэкономить (по сравнению с реальными потоками). Например, чтобы запускать некоторый код Lua только время от времени.

2
ответ дан 29 November 2019 в 03:46
поделиться

Я впервые использую Lua в игре, над которой работаю. Сторона C ++ моего приложения фактически содержит указатели на экземпляры каждого состояния игры. Некоторые игровые состояния реализованы на C ++, а некоторые - на Lua (например, состояние «игры»).

Циклы обновления и основного приложения находятся на стороне C ++. Я раскрыл функции, которые позволяют виртуальной машине Lua добавлять новые игровые состояния в приложение во время выполнения.

У меня еще не было проблем с медлительностью, даже при работе на оборудовании с ограниченными ресурсами (процессор Atom со встроенным видео). Функции Lua вызываются каждый кадр . Самая дорогая (по времени) операция в моем приложении - рендеринг .

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

Изменить: я использую Luabind , который, как я читал, в целом работает медленнее, чем другие структуры привязки и, конечно же, Lua C API.

6
ответ дан 29 November 2019 в 03:46
поделиться

О производительности 1: если main.lua не изменяется, загрузите его один раз с помощью lua_loadfile или loadfile , сохраните ссылку на возвращенную функцию, а затем вызовите ее при необходимости.

4
ответ дан 29 November 2019 в 03:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: