Жизнеспособна ли реализация вашего собственного языка сценариев?


21

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

Вы сделали свой собственный язык сценариев? Почему вы выбрали накатить свой вместо того, чтобы использовать существующий? С какими ресурсами вы консультировались во время разработки?


43
Моё личное эмпирическое правило таково: если вам нужно спросить других людей, является ли хорошей идеей бросать свой собственный _____, то это не очень хорошая идея.
Сэм Хочевар

2
Обратите внимание, что если вы реализуете свой собственный язык, люди должны изучать его и надеяться, что в вашем переводчике не будет ошибок, в то время как такие языки, как Lua, более популярны и гораздо реже имеют ошибки.
Ник Каплингер

2
@NickCaplinger бьет его по голове. Свертывание ваших собственных средств означает, что нет документации, нет сообщества, нет сторонних руководств, нет StackExchange и т. Д. Какие бы незначительные улучшения вы ни получили в синтаксисе или интеграции, они будут перевешены отсутствием поддержки, если вы не очень известный разработчик с миллионы поклонников.
Шон Мидлдитч

4
Также имейте в виду инструменты. Это моя проблема с D, Rust, Dart и т. Д. Ваш синтаксис сам по себе бессмысленен. Вам нужен правильный редактор, выделение, «Intellisense» (завершение кода), хорошая диагностика, поддержка рефакторинга, поддержка встроенной документации и т. Д., Чтобы действительно чего-то стоить. Не говоря уже о всех актуальных языковых возможностях, интеграции, эффективности и так далее.
Шон Мидлдич

1
Если вы программист на C ++ и вам не нравится LUA, попробуйте вместо этого JavaScript.
Zeel

Ответы:


42

Нет. По крайней мере, вероятно нет.

Это очень частый случай изобретения колеса - разработка игры, ошибка, которая все еще довольно популярна.

Если вы задаете этот вопрос, вы, скорее всего, будете зависеть от того, что делают другие, поэтому просто посмотрите, что Epic Games только что сделала с Unreal Engine:

  • У UE3 была нестандартная, неоптимизированная, трудно отлаживаемая вещь UnrealScript,
  • Если слух правдив, то его поддержка удаляется в UE4 в пользу горячо загружаемых библиотек C ++.

Как вы думаете, вы можете сделать лучше, чем Epic?

Создание языков программирования принадлежит создателям языков программирования , а не инженерам игр.

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

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

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

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

редактировать

Я только что посмотрел на список команд Cave Story, который вы связали. Уч:

<ECJx:y      [EC?] Jump           @ Jump to event Y if any npc with ID X is present

Я не хочу проявлять неуважение к разработчику, стоящему за Cave Story, но это прекрасный пример простого списка команд, который мутировал в неконтролируемом пользовательском языке сценариев. Это может все еще использоваться для отдельного разработчика или очень маленькой команды, но на этом этапе я советую переключиться на надлежащий Turing-полный и проверенный язык (например, Lua), где вы могли бы сделать:

if (npc.id == x) then
    jump_to_event(y)
end

Это значительно упростит ситуацию, когда, например, вам понадобится более сложное условие:

if (npc.id == x) or (npc.type == "enemy") then
    jump_to_event(y)
end

21
+1 «Создание языков программирования принадлежит создателям языков программирования, а не инженерам игр». Эта цитата не может быть более правильной. Пройдя курс по понятиям языка программирования, который вел парень, который был знатоком языков программирования, эти люди - другая порода. Один урок заставил меня осознать теорию CS и математику, которые входят в создание настоящего языка программирования. Это заставило меня ценить этих людей и их навыки еще больше. Они позволяют мне создавать игры, я остаюсь в стороне от них и позволяю им создавать языки.
Дин Найт

+1, я не знаю lua или пользовательский язык сценариев, но было совершенно очевидно, что происходит в lua, и именно там удобство и
простота

1
Нет ничего волшебного в том или другом, что делает невозможным изучение обоих. Unreal, возможно, удаляет UnrealScript, но они значительно улучшают и дополняют Kismet, чтобы быть способным и полным языком визуальных сценариев. Они не удалили UnrealScript, потому что это сбой, они удаляют его, потому что он устарел из-за значительно более сложных функций (горячая перезагрузка C ++, обновленный Kismit). Не принимайте это, чтобы означать, что я не согласен с вашей точкой зрения: написание собственного языка - это огромная трата времени, источник ошибок, причина больших кривых обучения и т. Д.
Шон Миддледич

2
@ ott-- Я тоже не боюсь, я хочу сказать, что расширение этой системы обозначений сделает ее все более и более сложной, в то время как использование надлежащего языка в первую очередь поможет в долгосрочной перспективе. Накладные расходы не актуальны по сравнению с простотой использования в этом случае, ИМХО.
Лоран Кувиду

1
Обратите внимание, что UnrealScript заменен Blueprints (но я держал пари, что мои коллеги вернутся). Горячая загрузка DLL является ортогональной функцией.
Сэм Хочевар

9

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

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

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

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

С какими ресурсами вы консультировались во время разработки?

Моим основным ресурсом была эта книга:

введите описание изображения здесь

Мне удалось выучить достаточно из этой книги, чтобы реализовать:

  • Лексер: это было почти тривиально, используя регулярные выражения, просто используя Regex.Match для идентификации и разделения токенов.
  • Парсер рекурсивного спуска: в основном одна функция для каждого правила в грамматике и несколько вспомогательных методов для просмотра и использования токенов. Я посмотрел на спецификации грамматики C # для вдохновения. Сложнее всего было иметь дело с арифметикой и приоритетами операторов отношений, не вдаваясь в бесконечную рекурсию.
  • Интерпретатор AST: используя шаблон проектирования посетителя, я обошел дерево, сгенерированное из синтаксического анализатора, и рекурсивно выполнил каждый узел инструкции.

Я бы остановился на этом, поскольку почти все, что мне было нужно, уже работало, за исключением одного - вызова и выдачи сопрограмм Unity3D глубоко внутри рекурсивного интерпретатора. Чтобы решить эту проблему, мне пришлось избавиться от рекурсии и снова повернуться к книге. На этот раз я добавил:

  • Компилятор: еще один посетитель, но вместо выполнения кода он генерирует список небольших атомарных инструкций из каждого узла AST (т. Е. Простой пользовательский язык ассемблера на основе стека). Такие операции, как цикл while или условие if, преобразуются в метки и инструкции типа goto. На этом этапе я также записываю скомпилированный скрипт на диск в виде двоичного файла.
  • Интерпретатор байт-кода: просто перебирает простой список инструкций. Без рекурсии теперь было легко интегрироваться с сопрограммами Unity3D.

Весь процесс занял около 2 недель с нуля знаний, и было очень весело :)

PS: В конце я также хотел добавить подсветку синтаксиса и intellisense для моего пользовательского языка в наших инструментах. Сцинтилла была спасателем в этом отношении. Я использовал следующую обертку:

http://scintillanet.codeplex.com/


5

Я видел это предложенное, но большинство людей предлагают Луа, но это не соответствует моему типу программирования.

Хорошо, давайте попробуем это с другой стороны: что в Lua вам не нравится? Это что-то, что легко поправимо, или это что-то фундаментальное?

Например, используйте ключевые слова, такие как then/do/endобозначение блока кода, а не хорошие фигурные скобки в стиле C / C ++. Если это твоя проблема ... это то, что ты можешь исправить. Все, что вам нужно сделать, это определить свой собственный маленький диалект Lua и написать простой инструмент преобразования, который преобразует ваш синтаксис в фигурные скобки в настоящий Lua.

Хотите + = в какой-то форме? Это также легко сделать в системе предварительной обработки. Просто включите утверждения формы expr1 += expr2в expr1 = expr1 + expr2.

Конечно, вам нужно будет найти способ определить, представляют ли пару фигурных скобок таблицу или do/endпару. И вы должны подключить систему предварительной обработки в Lua Переопределелив dofile, loadstringи другими стандартными функциями библиотеки Lua. Но все это в конечном итоге выполнимо.

Если такие проблемы, как эта, вас беспокоят, и вы слишком привязаны к одному стилю программирования, чтобы просто изменить способ кодирования (обратите внимание: это вообще ужасное качество для программиста), это гораздо более жизнеспособная альтернатива, чем просто писать на своем родном языке. Это займет максимум пару недель . Сравните это с годами , которые будут потрачены на правильный язык, с богатой поддержкой отладки и тому подобным.

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

И если вы действительно, действительно хотите быть хардкорным в этом, вы можете написать свой собственный язык, который вы компилируете в Lua. Таким образом, вы по крайней мере сможете использовать очень хорошо протестированную среду выполнения Lua, исключительный API Lua и другие базовые возможности Lua, все из вашего языка! Lua. Это займет время, но это не будут годы, которые вы потратите на что-то другое.


Мне кажется, что я мог бы просто закодировать функции, если бы использовал Lua. Такое ощущение, что я просто перемещаю код.
skiperic

1
@skiperic: Я не знаю, что вы имеете в виду под этим. Можете привести пример?
Николь Болас

Смотрите ответ Лорана выше.
skiperic

2
@skiperic: Это на самом деле не объясняет, что тебя беспокоит. Вы можете написать код на Lua? Да. И проблема в том ...?
Николь Болас

1
@BartekBanachewicz: Даже принимая, что это API C, он все же превосходит многие API сценариев на основе C ++, которые я видел. Это единственный API сценариев, который я бы на самом деле рассмотрел, используя raw , без какого-либо автоматизированного связывателя.
Николь Болас

3

Чтобы дополнить другие ответы, это не является строго бинарным вариантом. В существующем языке сценариев вы также можете создать свой собственный Domain-specific_language . Преимущества этого подхода:

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

Основным недостатком является то, что вы будете проектировать DSL с учетом ограничений вашего «базового» языка.


2

Это может иметь смысл в зависимости от механики вашей игры. Некоторые игры с достаточно простой механикой могут использовать интерпретируемый язык, чтобы уберечь себя от чрезмерно сложного кодирования Lua / Python, но экономия от сложности может не стоить слишком многого. Например, в одной из этих игр Interactive Novel можно было легко использовать пользовательский сценарий.

Если ваша игра включает в себя физический движок, различные игровые компоненты и различную сложность персонажей и способностей, вам определенно следует рассмотреть возможность просмотра других существующих языков сценариев, чтобы не тратить усилия на добавление необходимых функций к своему собственному или исправлять ошибки с помощью Это. Хотя Lua, скорее всего, самый быстрый, есть много других, которые вам могут понравиться больше за их синтаксис, и многие из них хвастаются тем, насколько легко они интегрируются с C. Python, Ruby и Angelscript - это лишь немногие. (Не стесняйтесь упоминать других в комментариях)

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


1
Lua также является очень популярным языком сценариев в разработке игр.
Филипп

Да, Луа используется повсеместно, но ОП отметил, что ему это не очень понравилось. Предпочтения стиля кодирования могут быть важны.
Katana314

1
« Например, в одной из этих игр« Интерактивный роман »может быть легко использован сценарий, написанный на заказ. « Очевидно, вы не видели Inform . Действительно, даже для текстовых приключений нет смысла придумывать свой собственный язык.
Никол Болас

1
@ Katana314: « Предпочтения стиля кодирования могут быть важны. » Честно говоря, мир был бы лучше, если бы программисты потеряли свою популярность по поводу «стиля кодирования». Мы все были бы лучшими программистами, если бы перестали думать, что <вставить предпочитаемый язык здесь> в корне лучше, чем у всех <вставить предпочитаемый язык здесь>. Использование языков, которым вам может не понравиться синтаксис символа builds и помогает избежать такого рода ошибок.
Никол Болас

1

Я говорю, пойти на это. В резюме это было бы дополнительным проявлением способностей. Однако имейте в виду, что вам нужна эта способность в первую очередь. Это не будет легко, это будет довольно сложно. Есть книги по этому вопросу, а также онлайн-учебники, но в конечном итоге это сводится к вам и вашему пониманию того, как работает компилятор, и как код анализируется и переводится.

Убедитесь, что вы начинаете с простого, часто тестируете и придерживаетесь своего идеала. Но всегда помните, LUA для вас.


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