Как Lua работает как скриптовый язык в играх?

Я немного туманно о том, что такое Lua и как игра, запрограммированная на C ++, будет использовать его. Я спрашиваю прежде всего о том, как он скомпилирован и запущен.

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

Или он действует как скрипт bash в Linux, где он просто выполняет программы, полностью отделенные от основной программы?

61 голос | спросил XSoloDolo 21 AMpMon, 21 Apr 2014 05:38:06 +040038Monday 2014, 05:38:06

6 ответов


84

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

Концептуально, общие шаги для включения сценариев следующие (я буду использовать псевдо-c для хоста и псевдо-lua для скрипта. Это не точные шаги, но больше похожи на общий поток, в который вы включаете скрипты )

  1. Создайте виртуальную машину в главной программе:

      VM m_vm = createVM ();
     
  2. Создайте функцию и выведите ее на виртуальную машину:

      void scriptPrintMessage (VM vm)
    {
        const char * message = getParameter (vm, 0); //первый параметр
        Е (сообщение);
    }
    
    //...
    
    createSymbol (m_vm, "print", scriptPrintMessage);
     

    Обратите внимание, что имя, в котором мы выставили функцию ( print ), не должно соответствовать внутреннему имени самой функции ( scriptPrintMessage )

  3. Запустите код сценария, который использует функцию:

      const char * scriptCode = "print (\" Hello world! \ ")"; //Также может быть загружен из файла, хотя
    doText (m_vm, scriptCode);
     

Вот и все. Затем программа течет следующим образом:

  1. Вы вызываете doText () . Затем управление передается на виртуальную машину, которая будет выполнять текст внутри scriptCode .

  2. Код сценария находит ранее экспортированный символ print . Затем он передаст управление функции scriptPrintMessage () .

  3. Когда закончится scriptPrintMessage () , управление вернет обратно на виртуальную машину.

  4. Когда весь текст в scriptCode будет выполнен, doText () закончится, и управление будет перенесено обратно в вашу программу на линии после doText () .

Итак, в общем, все, что вы делаете, это запуск программы внутри другой программы. Теоретически, вы ничего не можете сделать со сценариями, которые вы не можете обойтись без них, но эта абстракция позволяет вам делать интересные вещи очень легко. Некоторые из них:

  • Разделение проблем: это общий шаблон для написания игрового движка в C /C ++, а затем фактическая игра на языке сценариев, например, lua. Совершенно верно, игровой код может быть разработан полностью независимо от самого движка.

  • Гибкость: языки сценариев обычно интерпретируются, и поэтому изменение сценария не обязательно требует перестройки всего проекта. Сделано правильно, вы даже можете изменить сценарий и увидеть результаты без перезагрузки программы!

  • Стабильность и безопасность: поскольку сценарий запущен внутри виртуальной машины, если все сделано правильно, багги-скрипт не приведет к сбою хост-программы. Это особенно важно, когда вы разрешаете своим пользователям писать свои собственные скрипты в вашу игру. Помните, что вы можете создать столько независимых виртуальных машин, сколько хотите! (Я однажды создал сервер MMO, в котором каждое совпадение выполнялось на отдельной виртуальной машине lua)

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

Скрипты не идеальны. Существуют некоторые общие недостатки использования сценариев:

  • Отладка становится очень сложной: обычно отладчики, включенные в общие IDE, не предназначены для отладки кода внутри скриптов. Из-за этого отладка трассировки консоли гораздо более распространена, чем хотелось бы.

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

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

  • Интеграция с IDE: маловероятно, что ваша IDE будет знать, какие функции экспортируются из вашей программы, и, таким образом, такие функции, как IntelliSense и т. п., вряд ли будут работать с вашими сценариями.

    /li>
  • Производительность: будучи обычно интерпретируемыми программами и предназначена для абстрактной виртуальной машины, архитектура которой может отличаться от реального аппаратного обеспечения, сценарии обычно медленнее, чем собственный код. Однако некоторые виртуальные машины, такие как luaJIT и V8, действительно работают. Это может быть заметно, если вы очень сильно используете скрипты.

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

Как вы используете ваши скрипты, зависит от вас. Я видел сценарии, используемые для вещей так же просто, как и настройки загрузки, настолько сложными, как создание целых игр на языке сценариев с очень тонким игровым движком. Я когда-то даже видел очень экзотический игровой движок, который смешивал сценарии lua и JavaScript (через V8).

Скриптинг - это просто инструмент. Как вы его используете, чтобы создавать потрясающие игры, полностью зависит от вас.

ответил Panda Pajama 21 AMpMon, 21 Apr 2014 07:27:13 +040027Monday 2014, 07:27:13
6

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

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

ответил Josh Petrie 21 AMpMon, 21 Apr 2014 06:24:59 +040024Monday 2014, 06:24:59
4

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

Команды Lua вызываются только тогда, когда программа C ++ хочет их выполнить. Таким образом, код будет интерпретироваться только при его вызове. Я думаю, вы можете рассматривать Lua как скрипт bash, который выполняется отдельно от основной программы.

Как правило, вы хотите использовать языки сценариев для вещей, которые вы, возможно, захотите обновить или продолжить дальше по строке. Я видел, как многие компании используют его для графического интерфейса, поэтому он обеспечивает большую настраиваемость интерфейса. Предоставляя вам знать, как они создали свой интерфейс Lua, вы также можете самостоятельно изменить GUI. Но есть много других путей, которые вы можете использовать для использования Lua, таких как логика AI, информация об оружии, диалог символов и т. Д.

ответил M Davies 21 AMpMon, 21 Apr 2014 06:24:17 +040024Monday 2014, 06:24:17
3

Большинство языков сценариев, включая Lua, работают на виртуальной машине ( VM ), которая в основном, систему для сопоставления инструкции сценария с «реальной» инструкцией процессора или вызовом функции. Lua VM обычно работает в том же процессе, что и основное приложение. Это особенно верно для игр, которые его используют. Lua API предоставляет вам несколько функций, которые вы вызываете в собственном приложении для загрузки и компиляции файлов сценариев. Например. luaL_dofile () компилирует данный скрипт в Lua байт-код , а затем запускает его , Этот байт-код затем будет отображаться виртуальной машиной, запущенной внутри API, в собственные машинные инструкции и вызовы функций.

Процесс подключения родного языка, такого как C ++, с языком сценариев называется binding . В случае Lua его API предоставляет функции, которые помогут вам выставить собственные функции для кода сценария. Таким образом, вы можете, например, определить функцию C ++ say_hello () и сделать эту функцию вызываемой из сценария Lua. API Lua также предоставляет методы для создания переменных и таблиц с помощью кода C ++, который будет отображаться для скриптов при их запуске. Объединив эти функции, вы можете открыть все классы C ++ для Lua. Возможно также и обратное, Lua API позволяет пользователю изменять переменные Lua и вызывать функции Lua из собственного кода на C ++.

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

Надеюсь, это поможет прояснить некоторые ваши вопросы.

ответил glampert 21 AMpMon, 21 Apr 2014 06:24:09 +040024Monday 2014, 06:24:09
3

Поскольку никто не упомянул об этом, я добавлю его здесь для заинтересованных. Существует целая книга по теме Мастерство создания игр . Это фантастический текст, который был написан довольно давно, но он остается полностью актуальным сегодня.

В этой книге будет показано не только то, как языки сценариев вписываются в собственный код, но и учит тому, как реализовать собственный язык сценариев. Хотя это будет излишним для 99% пользователей, нет лучшего способа понять что-то, чем реализовать его (даже в очень простой форме).

Если вы когда-либо захотите написать игровой движок самостоятельно (или работаете только с движком рендеринга), этот текст бесценен для понимания того, как лучше всего использовать язык сценариев в вашем движке /игре.

И если вы когда-либо захотите создать свой собственный язык сценариев, это одно из лучших мест для начала (насколько мне известно).

ответил free3dom 22 AMpTue, 22 Apr 2014 11:45:55 +040045Tuesday 2014, 11:45:55
2

Во-первых, языки сценариев USUALLY не скомпилированы . Это большая часть того, что в целом определяет их как языки сценариев. Вместо этого они часто «интерпретируются». В основном это означает, что существует другой язык (который чаще всего компилируется ), который читается в тексте, в режиме реального времени и выполняет операции по очереди.

Разница между этим и другими языками заключается в том, что языки сценариев, как правило, более простые (обычно называемые «более высоким уровнем»). Тем не менее, они также имеют тенденцию быть немного более медленными, поскольку компиляторы стремятся оптимизировать множество проблем, которые возникают с «человеческим элементом» кодирования, и результирующий двоичный файл имеет тенденцию быть меньше и быстрее читать для машины. Кроме того, из другой программы, которая должна быть запущена на read , с запущенными программами, требуется меньше накладных расходов.

Теперь вы можете подумать: «Ну, я понимаю, что это немного легче, но почему бы кому-то отказаться от этой производительности для немного большей простоты использования?»

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

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

Изменить: причина, по которой lua имеет тенденцию быть довольно популярной в разработке игр, состоит в том, что она, возможно, является одним из самых быстрых (если не самых быстрых) общедоступных языков сценариев на земле. Однако с этой дополнительной скоростью он пожертвовал некоторым из своих удобств. Это, как говорится, все еще возможно более удобно, чем работать с C или C ++.

Важное редактирование: . После дальнейших исследований я обнаружил, что существует гораздо больше противоречий в отношении определения языка сценариев (см. Дихотомия Ousterhout ). Основная критика определения языка как «скриптового языка» заключается в том, что он не является ни значимым для синтаксиса, ни для семантики языка, что он интерпретируется или компилируется.

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

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

  • Они типизируются динамически
  • У них мало или вообще нет положений для сложных структур данных.
  • Программы в них (скрипты) интерпретируются

Кроме того, часто считается, что язык является языком сценариев, если он предназначен для взаимодействия и функционирования рядом с другим языком программирования (обычно это not считается языком сценариев).

ответил Gurgadurgen 21 AMpMon, 21 Apr 2014 06:21:41 +040021Monday 2014, 06:21:41

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132