Какая технология позволяет программировать в игре?


27

Есть некоторые игры, которые позволяют игроку писать / создавать сценарии в игре, например: Космические инженеры или Пси .

Я хочу использовать что-то похожее на одно из них, но мне было трудно найти информацию, поэтому мой вопрос:

Есть ли ветка программирования, которая охватывает способность программного обеспечения после компиляции запускать новый код, созданный пользователем?

Под ветвью программирования я имею в виду что-то вроде PTG (Procedural Terrain Generation).

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


22
Ну, наверное, «написание переводчиков»?
MatthewRock

2
Недавно я ответил на аналогичный вопрос , обсуждая термин « виртуальная машина » как термин для системы, в которой выполняется код пользователя, а также ссылаясь на статью «Шаблоны программирования игр», посвященную шаблону байт-кода, как средство реализации этого быстрее, чем обычный интерпретатор.
DMGregory

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

2
Программа Python может содержать сценарии Python. Это называется метапрограммирование. У большинства интерпретируемых языков есть это.
user6245072 26.09.16

1
AFAIK в Space Engineers, код скомпилирован код C # в изолированной среде (игра вышла с открытым исходным кодом, так что вы можете проверить, как это работает онлайн: github.com/KeenSoftwareHouse/SpaceEngineers ). По сути, игра поставляется с компилятором C #, а код разрешает доступ только к API-функциям игры, поэтому область действия программы ограничена только вами. И если вы играете в мультиплеер, то код запускается только на вашей машине (другие игроки / сервер просто видят последствия в игре)
Флориан Кастеллан,

Ответы:


42

Скрипты, написанные на скриптовых / встроенных / интерпретируемых языках, таких как «Lua», «Lisp» или «AngelScript» ( подробнее здесь ), могут обновляться во время игры [*], а затем интерпретироваться (= исполняться) на лету.

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

Некоторые соответствующие связанные вопросы:


[*] либо пользователем как частью игры, либо разработчиками для быстрой итерации / тестирования без перезапуска приложения


14
Я был бы осторожен, называя что-то «интерпретируемым языком». В лучшем случае это очень спорный термин.
Вондра

1
Computercraft (мод Minecraft) использует LUA в качестве языка сценариев для программирования задач в игре.
Tikeb

20
Я не очень понимаю суету. Лисп можно интерпретировать и компилировать. Мы здесь не для того, чтобы обсуждать, как классифицировать языки и interpretedявляется ли это хорошей классификацией; мы говорим OP, кто не знает об этом факте, что язык не нужно компилировать, но можно интерпретировать - и приведем несколько языков в качестве примера. Лисп интерпретируется? Да. Это скомпилировано? Тоже да! Но это выходит за рамки. Ответ может быть неточным с формулировкой, но он подходит для этой цели; это подталкивает OP в правильном направлении, и это то, что имеет значение. Вот, возьми мой +1.
MatthewRock

1
Хорошо, даже если язык только для компиляции, что мешает вам встроить IDE, компилятор и среду выполнения в вашу игру? Кроме бюджета.
Ордос

3
@DanielJour Хотя я бы согласился с тем, что теоретически язык может отличаться от его реализации (скомпилированной с машинным кодом против скомпилированного в байт-код для vm), это все еще полезно экономящее время предположение, что C компилируется, если не указано иное (и вы можете себе представить, взгляды, которые вы получите, если будете каждый раз спрашивать: «подождать, скомпилировать C или интерпретировать C?»). Для целей ОП он должен смотреть на языки, поддерживающие устный перевод; могут ли они быть скомпилированы или нет, это не проблема, потому что он не использует его.
Блэкхок

12

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


11

Вы ищете способ изменить код на некоторые действия. Это именно то, что делают переводчики .

Посмотрите на Python. Вы управляете этим, и бац! Вы высадиться в REPL ( R EAD E VAL P Ринт L полокоть).

Вы определяете функцию "привет", которая печатает "Привет, мир". И вот оно!

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

То же самое относится и к играм. Вместо REPL у вас есть игра с модулем REPL. Игра, вероятно, запускает REPL, а затем запускает все остальное в этом REPL, поэтому у вас есть доступ к данным и вы можете их активно изменять.

Если вы работаете с огромными языками, такими как C ++, они, как правило, менее динамичны и, вероятно, скомпилированы. Вы хотите немного проще. Вы либо создаете свой собственный язык, либо используете какой-то существующий (например, CoffeScript, Squirrel, Lua, Scheme, ...)

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


2

Если язык программирования в игре был разработан только для игровых целей, то это язык, специфичный предметной области .

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

Простой запуск неанизированного пользовательского кода на языке общего назначения (например, python или perl) изнутри вашей игры может позволить пользователю связываться с вещами, с которыми ему не следует связываться. Но это зависит от вашей игры. Если вы не возражаете против того, чтобы пользователи занимались такими вещами, как открытие новых окон внутри вашей игры или что угодно, вы можете использовать язык общего назначения и выставлять привязки к определенным функциям вашего игрового мира.


1

Есть два примера, которые я могу придумать с головы до головы. Оба, кажется, делают именно то, что вы просите.

Первый - это крики. https://screeps.com/ Вы можете прочитать много о том, как это достигает этой цели в http://support.screeps.com/hc/en-us/articles/205960931-Server-side-architecture-overview

Второй - ComputerCraft http://www.computercraft.info/ Они не вдавались в подробности того, как он работает, но немного можно увидеть в их вики http://www.computercraft.info/wiki/Main_Page.

По сути, основная игра запускает интерпретатор в отдельном потоке, а затем позволяет этому потоку манипулировать игровым миром посредством вызовов API.

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

Обычно, чтобы начать что-то подобное, требуется совсем немного работы. Тебе нужно

  • менеджер потоков, который защищает цикл вашей игры (не позволяет потоку блокировать цикл или потреблять много ресурсов). В обоих примерах используется ограничитель времени.
  • переводчик для управления языком. LUA довольно распространен в наши дни.
  • набор вызовов API, которые изменяют игровой мир. Какой интерес является языком программирования, если вы ничего не можете с ним сделать.
  • реализация управления ресурсами. Другими словами, способ хранить файлы кода и ссылаться на них в игре.

Нет единой ветви программирования, которая бы занималась всеми этими проблемами. Но вам понадобится прочная основа для многопоточности и общие знания о том, как работает переводчик.


0

Скомпилированный исполняемый файл должен содержать анализатор , способный читать внешний программный код . Код программы не обязательно должен выглядеть как C или Python или xyz - это могут быть любые описательные данные, которые подходят для рассматриваемой цели. Например, шведский или азбука Морзе.

Код внешней программы должен иметь синтаксис , чтобы синтаксический анализатор понимал его, как он читает его символ за символом. Синтаксис может описывать (и код может содержать) идентификаторы, числовые значения, операторы и т . Д.

Парсер исправлен (скомпилирован), но работает с гибким внешним кодом.

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

Синтаксический анализатор может читать внешний программный код при запуске исполняемого файла , или он может читать (части) его ad hoc , или он может перечитывать его для каждого кадра (будет неэффективно), или код может даже быть напечатан вручную и отправлено парсеру, когда он готовится (например: «переместить блок X вперед на 5 шагов» [enter]).

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

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

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

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

sock = Socket.New (AddressFamily.InterNetwork, SocketType.Stream ProtocolType.Tcp) [ENTER]

... а потом пойти на 30 ... нет, 45-минутный перерыв на кофе :-). При возврате «носок» существует и готов к дальнейшему использованию, печатая больше вручную или продолжая автоматизацию интерпретатора.


Существует распространенное заблуждение, что интерпретируемый язык должен быть медленным. Неправда. В зависимости от различных факторов, которые делают это обсуждение слишком широким для комментариев, интерпретируемый язык может быть на величину или меньше медленнее, быстрее или даже для некоторых операций быстрее, чем язык управления, который считается быстрым (обычно C). Пример с сокетом, вероятно, будет работать более или менее так же, как в C, поэтому пример вводит в заблуждение. Вы также можете переопределить скомпилированные функции во время выполнения на некоторых языках, и интерпретация не означает просто «выполнение одной инструкции за раз».
MatthewRock

Конечно, интерпретируемый язык также может работать быстрее - ведь выполняется только байт-код, а выполнение может быть намного лучше оптимизировано, в зависимости от автоматизации интерпретатора. Кроме того, некоторые интерпретаторы могут компилировать, из кода, части кода в байт-код (и выполнять), ad hoc. Этот пример является просто примером свободы: «Выполнение одной инструкции за раз»? Ну, это упрощение, возможно, добавьте «пока будущий код будет гибким».
Штормград

Думайте о «сценарии» больше как о сценарии фильма - вам по-прежнему нужны актеры, и они определяются непосредственно с точки зрения биологии и социологии, а не театральных наук (хотя в конечном итоге они основаны на биологии и социологии), поскольку эти языки более подходит для этой цели, но не для других :)
rackandboneman
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.