LINUX.ORG.RU

Какой язык выбрать для внутренних игровых скриптов?

 , , , ,


1

3

Сам движок на C++, для скриптов выбираю между Lua и Python. Что лучше? Или есть другие лучше? Можно ли использовать Rust как скриптовой язык? Он вроде как лучше, чем C и C++, но говорят, что его используют только приверженцы ЛГБТ и модераторы (что одно и то же).

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

На каком языке не пишут модераторы? Не хочется зашквариться.



Последнее исправление: KundaMasha (всего исправлений: 6)

Rust, …говорят, что его используют только приверженцы ЛГБТ.

Не только. Ещё трапы и феминаци.

rupert ★★★★★
()

Если больно писать на голом Lua, можно взять что‐то, что в него собирается (ещё и без потери производительности в случае Fennel).

Warez
()

Я бы из-за универсального применения выбрал Python.

PS Модераторы хрен вы TOR победите!

anonymous
()

Что лучше? Или есть другие лучше?

Есть. Lisp, Io, Tcl.

Можно ли использовать Rust как скриптовой язык? Он вроде как лучше, чем C и C++, но говорят, что его используют только приверженцы ЛГБТ.

ЛГБТ мягко сказано. За использование Rust в качестве скриптоты убивать надо, ибо это overhead чуть больше, чем всюду. Я бы брал Lua (простой как шпала), Ruby (тут много хорошего можно на основе ООП сделать, синтаксис приятнее питонячего + возможность DSL писать хорошие) или Scheme/ECL (скорее даже его, ибо можно было бы сделать DSL и заточить под написание логики внутриигровой любой макакой).

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

А при чём тут Dropbox и профиты от использования языка?

silver-bullet-bfg ★★
()
Ответ на: комментарий от peregrine

По скорости +/- одинаковые. Тебе не числодробилки молотить, а switch/case и примитивные алгоритмы писать. RPG maker его пользует, ЕМНИП, проблем ни у кого не возникло.

Поэтому проблем не будет. Если хочется вот прямо совсем быстрое - lua, scheme, ecl, tcl. Последний вот прямо очень быстр и может быть синтаксис сделать любой через DSL, чтобы было не сложно писать вообще.

silver-bullet-bfg ★★
()
Ответ на: комментарий от silver-bullet-bfg

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 4)
Ответ на: комментарий от peregrine

Это уже разные параметры - цена поддержки и скорость работы. Тут надо выбирать, что тебе важнее. Ну и тогда JavaScript лучше. Программистов на JS ещё больше.

Если ты дашь очень простой DSL то вообще всё равно, что там внутри или на базе какого ЯП на самом деле. Если беспокоит количество макак - то я бы брал JS, их в десятки раз больше)

silver-bullet-bfg ★★
()
Ответ на: комментарий от silver-bullet-bfg

Программистов на JS ещё больше

JS тоже отличный вариант. Но с NodeJS, а ноду встроить ещё проблемнее, чем Python. Ну а макак там не в десятки раз больше, процентов на 20 и часть из них только для веба

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 2)
Ответ на: комментарий от peregrine

JS тоже отличный вариант.

Я про то же.

Но с NodeJS, а ноду встроить ещё проблемнее, чем Python.

Зачем всю Node тащить? Можно просто V8.

Ну а макак там не в десятки раз больше, процентов на 20 и часть из них только для веба

А какая разница - для веба или нет? Алгоритмы везде одни и те же. Разница только в интерфейсах доступа к данным.

silver-bullet-bfg ★★
()
Ответ на: комментарий от silver-bullet-bfg

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

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Ну - +/- так же. Фронты рисуют для этого интерфейс. По своей практике - даже чаще понимают процесс лучше, т.к. их задача дать интерфейс. Но это правда ИМХО и схоластика.

В любом случае можно взять V8 и на его основе сделать скрипты (их работу). А toolkit может и сохранять NodeJS, на выходе давая просто bundle для v8

silver-bullet-bfg ★★
()
Последнее исправление: silver-bullet-bfg (всего исправлений: 2)

Какой язык выбрать для внутренних игровых скриптов?

Racket, Lua.

Hertz ★★★★★
()
Последнее исправление: Hertz (всего исправлений: 1)
Ответ на: комментарий от Egor_

«эмуляция» ООП в луа занимает 10 строк кода в начале проекта.

Можно глянуть на эти 10 строк? Там вроде ж обычный prototype-based, непонятно что как и зачем нужно эмулировать.

dimgel ★★★★★
()

Лиспы или хранение скриптов в любом другом представлении AST уже советовали?

AST можно строить визуальным программированием(аля скрэч)

nihirash ★★★
()
Ответ на: комментарий от dimgel

«эмуляция» ООП в луа занимает 10 строк кода в начале проекта.

Там вроде ж обычный prototype-based, непонятно что как и зачем нужно эмулировать.

привыкшие к ООП хотят иметь корневой базовый класс и готовые функции для создания подкласса класса и для создания нового инстанса класса Class:new().
внутри реализации этих функций автоматически прописываатся метатаблица, у которой её __index указывает на неё саму
смысл всего этого - спрятать прототипную часть внутрь, а наружу вывести привычный ООП-интерфейс.
Вот это и занимает 10 строк.
Если не жалко ещё 10 строк, то можно написать функцию для получения класса через множественное наследование от нескольких других классов.

http://lua-users.org/wiki/ObjectOrientedProgramming

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

Egor_
()
Ответ на: комментарий от dimgel

Про интеграцию lua в многопоточное приложение см. тут

мыши опять грызут кактус?
в луа нет многопоточности, не было и не будет
костыль lua_lock - это резервное средство для повышенной дуракоустойчивости, а не для организации многопоточности.
единственный работающий способ - запустить в каждом потоке свою виртуальную машину луа, а для обмена данных использовать сериализацию: любой объект превращается в строку (эту часть можно написать на луа), Сишечка передаёт строку в другой поток другой виртуалке, а там строка десериализуется в объект (можно опять кодом на луа).
причём сериализовать можно всё, включая луа-функции
сишную функцию можно десериализовать только если она уже есть на принимающей стороне (напр, на принимающей виртуалке надо вызвать ту же самую require-либу, которая и создала эту сишную функцию на отправляющей виртуалке)

Egor_
()
Ответ на: комментарий от Harald

Это же DELIRIUM, ты что, не узнал? Он только сейчас не шутит про геев, так как его просто к чертям забанят, потом, думаю, его понесёт

anonymous
()
Ответ на: комментарий от Egor_

мыши опять грызут кактус?

Да луа – вообще какашка та ещё. Но т.к. я на эту тему уже давно высказывался (и был оплёван), то решил не повторяться.

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

Толково. Интересно, пришло бы мне самому это в голову, занимайся я собственно прикручиванием lua к многопоточному проекту.

dimgel ★★★★★
()
Ответ на: комментарий от dimgel

Да луа – вообще какашка та ещё. Но т.к. я на эту тему уже давно высказывался (и был оплёван)

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

Egor_
()

stasolog у тебя так бомбит, что ты следишь за мной?

KundaMasha
() автор топика
Ответ на: комментарий от Egor_

но сперва хотел бы узнать ваши аргументы

Состоялся выпуск тайлового оконного менеджера i3 4.16 (комментарий)

Это было смутное воспоминание о давнишних впечатлениях с awesome WM. Сейчас впечатления с торговым терминалом quik:

  • терминологические бредни:

    • ~= вместо != (ну нахера?!);

    • индексы с 1 (бог им судья);

    • единственная структура, которая у нормальных людей называется Map, здесь почему-то называется таблицей;

    • хорошо или плохо что 0 приводится к true – вопрос философский, в целом удобно, но точно необщепринято;

    • nil – с одной стороны вроде бы и хорош, с другой – используется как маркер конца массива даже если после него есть значения; в т.ч. массива параметров arg, что дико неудобно. Вот что мешало поле length из коробки сделать?

    • что-то было ещё из этой же серии, но не помню.

  • крайняя куцость языка, e.g.:

    • нет оператора continue; здравствуй куча вложенных if-ов.

    • битовые операции завезли только в 5.3 (бакпортнули либой в 5.2); не смотрел, но видимо как и в js они должны быть на младших 32 битах, т.к. в lua все числа – double.

    • вместо x?y:z есть x and y or z, причём здесь nil от false неотличимы, т.е. эквивалент x?nil:z тут не написать (можно впрочем написать эквивалент not x ? z : nil). Некритично, но эдакое напоминание – «не забывай на чём пишешь».

А вот в остальном (и в целом) как ни странно вполне понравилось. Возможно потому что в этот раз я писал скрипты с нуля (в т.ч. классы с наследованием), и в quik-овском API в отличие от awesome-овского своих классов нет, так что запутаться было негде. Ну и учебник проштудировал прежде чем браться – не то чтобы совсем насквозь, некоторые главы с описаниями как выражать сложные идиомы имеющимися простыми средствами пролистывал, т.к. идея уже была понятна. Прототипное наследование выглядит проще и чище чем в js.

Разве что if уже две недели на автомате закрываю fi вместо end, #$%ный баш.

dimgel ★★★★★
()
Ответ на: комментарий от dimgel

~= вместо != (ну нахера?!);

мысля у автора была что ~ это NOT, поэтому ~= это не равно
в луа 5.3 добавился оператор ~ побитовый NOT
как видишь, всё логично

индексы с 1 (бог им судья);

где-то видел упоминание одного забавного холивара «паскаль против си»
сторонник си перечислил недостатки паскаля, составив список типа такого:

  1. индексы символов в строках начинаются с 1, а не с 0
  2. ещё что-то
  3. ещё что-то

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

в луа индексы начинаются с единицы, потому что во всех стандартных функциях в луа, где принимаются индексы, индексы можно считать как вперёд с начала (1,2,3), так и назад с конца (-1,-2,-3). Если бы индексы начинались с нуля, то фича не получилась бы такая красивая и симметричная.

единственная структура, которая у нормальных людей называется Map, здесь почему-то называется таблицей;

таблица в луа - это одновременно и map, и array, и struct.
я б назвал такую структуру данных «монстроконтейнер», но автор луа выбрал более банальное и неудачное имя.

хорошо или плохо что 0 приводится к true – вопрос философский, в целом удобно, но точно необщепринято;

ну, в сишечке 0 приводится в false потому что язык со строгой типизацией, и там переменная типа int может хранить только числа и не может хранить null/undefined.
а в луа можно хранить в любой переменной nil (значение, выражающее факт отсутствия значения), поэтому 0 - это присутствующее значение, поэтому true.

nil – с одной стороны вроде бы и хорош, с другой – используется как маркер конца массива даже если после него есть значения; в т.ч. массива параметров arg, что дико неудобно. Вот что мешало поле length из коробки сделать?

ты ж сам только что сказал, что в луа таблица - это map
какой нахрен length у map?
length бывает только у массивов
nil - это отсутствие значения, так откуда nil возьмётся в массиве, например, чисел?
ты хочешь чего-то очень странного (массив чисел с дырами)?
у сишников такого типа данных нет, и ничего, живут как-то
но в луа это можно сделать: хочешь хранить длину - храни в поле .n, не хочешь хранить длину - не храни, выбор за тобой, ничего «из коробки» здесь не нужно
если ты передаёшь аргументы в функцию, включая nil, и хочешь узнать их количество, то для этого есть select(‘#’,…)

нет оператора continue; здравствуй куча вложенных if-ов.

continue можно сделать через break на промежуточный фиктивный однократно-выполняемый цикл:

for ... do -- твой цикл
  repeat
    ....
    break  -- это твой continue
    ....
    break  -- это твой continue
    ....
  until true
end

битовые операции завезли только в 5.3 (бакпортнули либой в 5.2); не смотрел, но видимо как и в js они должны быть на младших 32 битах, т.к. в lua все числа – double

в 5.3 завезли int64, и битовые операции - 64-битные
в 5.2 числа только double, и поэтому битовые операции 32-битные

вместо x?y:z есть x and y or z, причём здесь nil от false неотличимы, т.е. эквивалент x?nil:z тут не написать (можно впрочем написать эквивалент not x ? z : nil). Некритично, но эдакое напоминание – «не забывай на чём пишешь»

не ленись, пиши через if - производительность будет точно такая же

«Could be an int, a string, a list», an object, a class, a method…

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

Разве что if уже две недели на автомате закрываю fi вместо end, #$%ный баш.

у меня проблема с if-ами при переключении между паскалем и луа
никак не привыкну, что там if-end, а там if-begin-end

Egor_
()
Последнее исправление: Egor_ (всего исправлений: 1)
Ответ на: комментарий от Egor_

как видишь, всё логично

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

таблица в луа - это одновременно и map, и array, и struct.

Не надо демагогии. Это именно map, с неупорядоченными ключами (о чём в книге сказано явно). Всё остальное – интерпретации и способы использования для эмулирования поведения других структур.

какой нахрен length у map?

И тем не менее в lua он есть. Но он считает концом массива первое вхождение nil, а не за-последним вхождением не-nil. Что есть бред собачий.

ты хочешь чего-то очень странного (массив чисел с дырами)? у сишников такого типа данных нет, и ничего, живут как-то

Ты мне сишниками не пеняй. Мы говорим про динамически-типизированный язык.

но в луа это можно сделать: хочешь хранить длину - храни в поле .n

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

не ленись, пиши через if - производительность будет точно такая же

Замечательный аргумент. Правильно, за компактный и выразительный синтаксис бьются идиоты, которые ленятся клавиатуру топтать.

так это ж именно ты кладёшь значения в переменную

А, теперь ясно. Всё с тобой. Жаль только потраченного на переписку времени. Откланиваюсь.

dimgel ★★★★★
()
Ответ на: комментарий от dimgel

выдумывает новую нотацию вместо общепринятой

с каких пор язык си стал стандартом всех остальных языков? )))
мне не нравятся ~= и !=, я хочу другую общепринятую нотацию <>

встроенный оператор взятия длины массива таки есть, но ведёт себя по-идиотски.

ещё раз для тех кто в танке: значение nil предназначено для факта отсутствия значения
в массиве не должно быть nil
а если ты применяешь оператор для обычных массивов к массиву с дырами, то ты ССЗБ

так это ж именно ты кладёшь значения в переменную

А, теперь ясно. Всё с тобой.

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

Egor_
()
Последнее исправление: Egor_ (всего исправлений: 4)
Ответ на: комментарий от andalevor

любой язык с динамической типизацией даёт больше гибкости

В чём это выражается?

например, в полиморфизме
вот в луа есть функции, их можно вызывать: func(arg1, arg2)
и есть таблицы, которые вызывать нельзя, но если в метатаблице создать метаметод __call, то можно: tbl(arg1, arg2)

пусть кто-то (либа1) создала функцию func, а другой код (либа2) эту функцию вызывает
и тут в проект пришли вы, и видите проблему: функция тяжёлая, и часто вызывается с одними и теми же аргументами, возвращая каждый раз одни и те же значения. то есть, совершается лишняя вычислительная работа, есть простор для оптимизации.

а теперь следите за руками: вам не нужно редактировать существующий код, чтобы добавить туда кэширование результата. вместо этого вы ищите третью либу, которая реализует функцию tbl = memoize(func), превращающую любую функцию в таблицу, хранящую уже ранее посчитанные значения, и вызывающую (через метаметод __index) вычислительный расчёт только при отсутствии готового результата.

вы добавляете в код проекта только одну строку:
func = memoize(func)
до этой строки func - это функция, после этой строки func - это таблица, всё в той же переменной!
ни либа1 (создавшая func), ни либа2 (использующая func) не подозревают об этом обмане и продолжают работать как обычно
в этом и есть польза полиморфизма: новый func выглядит как утка и крякает как утка, хотя это уже крокодил под маской утки.

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

Egor_
()
Ответ на: комментарий от Egor_

до этой строки func - это функция, после этой строки func - это таблица, всё в той же переменной!

А потом придёт Вася и в следующей строке засунет в func строку. В rust, к примеру, есть shadowing и там также можно подменить func. Только компилятор убедиться, что func действительно можно вызвать и, что количество и тип параметров соответствуют.

вам не нужно надстраивать синтаксис языка

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

andalevor ★★
()
Ответ на: комментарий от andalevor

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

dimgel ★★★★★
()
Ответ на: комментарий от andalevor

Только компилятор убедиться, что func действительно можно вызвать и, что количество и тип параметров соответствуют.

в луа нет такого понятия «количество и тип параметров»
и как мне объяснить рабу, что такое свобода?…

Egor_
()
Ответ на: комментарий от dimgel

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

вместо того, чтобы думать над абстракциями из предметной области, «макаки статической типизации» думают 90% времени кодинга над тем, а не ругнётся ли на них компилятор
компилятор для них не средство, а божество, многочисленные причуды которого нужно всячески ублажать и думать только так, как велит компилятор, шаг влево-вправо - расстрел
и среди макак бытует миф, что если компилятор будет многое позволять, то макаки непременно насрут везде где могут, пользуясь вседозволенностью. хотя, может быть, именно в этом они как раз правы ))) бытие порождает сознание

Egor_
()
Ответ на: комментарий от dimgel

хотя аннотация @Cache, выполняющая ту самую мемоизацию, которую он тут преподносит как откровение

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

Egor_
()
Ответ на: комментарий от Egor_

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

В 1С динамическая типизация присутствует.
Поэтому в 200 строк можно написать алгоритм загрузки например из MySQL данных таблиц в 1С и наоборот.

Ныне правда могу ту же функциональность реализовать в 100 строках C++.

Вот что скажу «знатокам» C/C++

Нечего на зеркало пинять, коли морда крива.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Вот что скажу «знатокам» C/C++

С другой стороны они частично правы - «на блюдечке такого» API нет.

Владимир

anonymous
()
Ответ на: комментарий от anonymous

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

peregrine ★★★★★
()
Ответ на: комментарий от dimgel

единственная структура, которая у нормальных людей называется Map, здесь почему-то называется таблицей;

google://hash+table ?

korvin_ ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.