A implementação de sua própria linguagem de script é viável?


21

Estou codificando um jogo de beat 'em up em C ++ e chegou a hora de implementar scripts para eventos, gatilhos, cenas etc. Eu li na internet e obtive informações suficientes. Minha primeira solução seria implementar minha própria linguagem de script como a do Cave Story . Eu já vi isso sugerido, mas a maioria das pessoas sugere lua, mas isso não parece se encaixar no meu tipo de programação.

Você criou sua própria linguagem de script? Por que você escolheu fazer o seu próprio em vez de usar um já existente? Quais recursos você consultou durante o desenvolvimento?


43
Minha regra pessoal é: se você precisar perguntar a outras pessoas se é uma boa ideia lançar seu próprio _____, então não é uma boa ideia.
21713 Sam on Hocevar

2
Observe que, se você implementar seu próprio idioma, as pessoas deverão aprender e esperar que não haja erros no seu intérprete, enquanto idiomas como Lua são mais populares e muito menos propensos a ter erros.
perfil completo de Nick Caplinger

2
@NickCaplinger acerta na cabeça. Rolar para si próprio significa que não há documentação, comunidade, tutoriais de terceiros, StackExchange etc. Quaisquer pequenos avanços na sintaxe ou na integração serão compensados ​​pela falta de suporte, a menos que você seja um desenvolvedor realmente conhecido. milhões de fãs.
Sean Middleditch

4
Também tenha em mente as ferramentas. Esse é o meu problema com D, Rust, Dart, etc. Sua sintaxe é inútil por si só. Você precisa de um editor adequado, destacando "Intellisense" (conclusão de código), bons diagnósticos, suporte à refatoração, suporte a documentação em linha etc. para realmente valer qualquer coisa. Sem mencionar todos os recursos reais de linguagem, integração, eficiência e assim por diante.
Sean Middleditch

1
Se você é um programador C ++ e não gosta do LUA, tente o JavaScript.
zeel

Respostas:


42

Não. Pelo menos, provavelmente não.

Este é um caso muito frequente de reinventar a roda no desenvolvimento de jogos, um erro que ainda é bastante popular.

Se você está fazendo essa pergunta, é muito provável que seja influenciado pelo que os outros fazem, então veja o que a Epic Games acabou de fazer com o Unreal Engine:

  • O UE3 tinha uma coisa UnrealScript personalizada, estranha, não otimizada e difícil de depurar,
  • Se o boato for verdadeiro, seu suporte será removido no UE4 , em favor de DLLs C ++ recarregáveis ​​a quente.

Você acha que pode fazer melhor que a Epic?

A criação de linguagens de programação pertence aos criadores da linguagem de programação , não aos engenheiros de jogos.

Leva anos e anos para que um idioma se torne totalmente maduro e seu conjunto de ferramentas que o acompanha (compilador, vinculador, intérprete, depurador ...) utilizável. Atualmente, você tem muitas soluções disponíveis, então não há absolutamente nenhuma razão real para começar uma coisa nova do zero, pelo menos não se o objetivo é simplesmente criar um jogo. Período.

Para responder às suas perguntas secundárias, não, por esses mesmos motivos, nunca implementei minha própria linguagem de script. Mas sofri muito com alguns mal cozidos. Como eles foram criados com um recurso muito restrito em mente, eles sempre tiveram esses pequenos truques insanos que o deixam louco. Muitas vezes, você passa muito tempo tentando solucionar as limitações do idioma em vez de apenas fazer o seu jogo.

Se o motivo pelo qual você deseja criar uma linguagem é porque ela é destinada ao uso por pessoas que não conhecem muito bem a programação ou se você acredita que precisa disso porque deseja algo muito específico do domínio, deixe-me dizer que também razões ruins. Você pode escrever uma API de nível muito alto com funções que do_what_they_say_and_say_what_they_do()e algum código clichê muito simples que expõe seu uso básico. Seus usuários não tão técnicos terão prazer em aprender um pouco de programação e você ficará feliz em não ser limitado por uma linguagem mal implementada.

Portanto, como isso parecerá um tanto abrupto ou até severo, direi que há um caso em que poderia fazer sentido: se você quiser aprender como é criada uma linguagem de script. Mas, por favor, por favor, se você fizer isso: não force outras pessoas a usá-lo.

Editar

Acabei de dar uma olhada na lista de comandos do Cave Story que você vinculou. Ai:

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

Não quero mostrar desrespeito ao desenvolvedor por trás do Cave Story, mas este é um exemplo perfeito de uma lista de comandos simples que sofreu uma mutação em uma linguagem de script personalizada incontrolável. Isso ainda pode ser usado por um único desenvolvedor ou por uma equipe muito pequena, mas, neste estágio, aconselho a mudar para uma linguagem Turing completa e bem testada (por exemplo, Lua), onde você pode fazer:

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

Isso facilitará muito as coisas quando, por exemplo, você precisará de uma condição mais complexa:

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

21
+1 "A criação de linguagens de programação pertence aos criadores da linguagem de programação, não aos engenheiros de jogos." Esta citação não pode estar mais correta. Tendo participado de uma aula de conceitos de linguagem de programação ministrada por um cara que era especialista em linguagens de programação, essas pessoas são de uma raça diferente. Uma aula me fez perceber a quantidade de teoria e matemática de CS que são necessárias para criar uma linguagem de programação real. Isso me fez apreciar ainda mais essas pessoas e suas habilidades. Eles me deixaram criar os jogos, eu fiquei fora do caminho deles e deixei que eles criassem os idiomas.
Dean Cavaleiro

+1, eu não sei lua ou a linguagem de script personalizado, mas era evidente exatamente o que estava acontecendo na lua e é onde a usabilidade é importante
RhysW

1
Não há nada mágico sobre um ou outro que impossibilite o aprendizado de ambos. O Unreal talvez esteja removendo o UnrealScript, mas eles estão aprimorando e preenchendo o Kismet para ser uma linguagem de script visual capaz e completa. Eles não removeram o UnrealScript porque é uma falha, estão removendo-o porque está fora de moda por recursos significativamente mais difíceis (C ++ de recarga a quente, Kismit atualizado). Não levar isto para dizer que discordo com o seu ponto: escrever seu próprio idioma é um enorme desperdício de tempo, uma fonte de erros, e uma causa de grandes curvas de aprendizagem, etc.
Sean Middleditch

2
@ ott-- Também não tenho medo, meu argumento é que expandir essa notação a tornará cada vez mais complicada, enquanto o uso de uma linguagem adequada em primeiro lugar ajudará a longo prazo. A sobrecarga não é relevante em comparação com a facilidade de uso nesse caso, IMHO.
Laurent Couvidou

1
Observe que o UnrealScript é substituído pelo Blueprints (mas aposto que meus colegas voltarão). DLLs de carregamento quente é um recurso ortogonal.
21713 Sam_Hocevar

9

Você criou sua própria linguagem de script e por que escolheu criar sua própria linguagem em vez de usar uma já existente?

Eu tenho, embora tenha emprestado a sintaxe de outros idiomas. No geral, foi uma ótima experiência de aprendizado e, no meu caso, não foi tão difícil porque o idioma era simples.

Fiz isso principalmente porque queria usar uma sintaxe comum no estilo C para meus scripts, pois todos da equipe estavam familiarizados com isso.

Também estava interessado em aprender um pouco sobre a implementação de linguagens de programação e, como só precisava de um subconjunto muito simples de recursos (variáveis, aritmética, condicionais, loops e chamada de funções ou corotinas no jogo), decidi experimentá-lo.

Quais recursos você consultou durante o desenvolvimento?

Meu principal recurso foi este livro:

insira a descrição da imagem aqui

Consegui aprender o suficiente com este livro para implementar:

  • Um lexer: que era quase trivial usando expressões regulares, apenas usando Regex.Match para identificar e dividir tokens.
  • Um analisador de descida recursiva: basicamente uma função para cada regra na gramática e alguns métodos auxiliares para procurar e consumir tokens. Eu olhei para a especificação da gramática C # para inspiração. A parte mais difícil foi lidar com as precedências aritméticas e do operador de relações sem entrar em recursão infinita.
  • Um intérprete AST: usando o padrão de design do visitante, atravessei a árvore gerada a partir do analisador e executei cada nó de instrução recursivamente.

Eu teria parado por aí, já que quase tudo o que precisava já estava funcionando, exceto por uma coisa: chamar e render corotinas do Unity3D profundamente dentro do intérprete recursivo. Para resolver esse problema, tive que me livrar da recursão e voltei-me novamente ao livro. Dessa vez, acabei adicionando:

  • Um compilador: outro visitante, mas em vez de executar o código, ele gera uma lista de instruções atômicas pequenas de cada nó do AST (ou seja, uma linguagem de montagem personalizada simples baseada em pilha). Operações como um loop while ou uma condição if são convertidas em etiquetas e instruções do tipo goto. Neste ponto, também escrevo o script compilado no disco como um arquivo binário.
  • Um intérprete de bytecode: simplesmente itera sobre uma lista simples de instruções. Sem a recursão, agora era fácil integrar-se às corotinas do Unity3D.

Todo o processo levou cerca de 2 semanas a partir do zero conhecimento e foi muito divertido :)

PS: No final, eu também queria adicionar realce de sintaxe e inteligência para o meu idioma personalizado em nossas ferramentas. Scintilla era um salva-vidas a esse respeito. Eu usei o seguinte wrapper:

http://scintillanet.codeplex.com/


5

Eu já vi isso sugerido, mas a maioria das pessoas sugere lua, mas isso não parece se encaixar no meu tipo de programação.

OK, vamos tentar de outro ângulo: do que Lua você não gosta? É algo que é facilmente corrigível, ou é algo fundamental?

Por exemplo, use o uso de palavras-chave, como then/do/endpara denotar bloco de código, em vez de boas chaves no estilo C / C ++. Se esse é o seu problema ... é algo que você pode corrigir. Tudo o que você precisa fazer é definir seu próprio dialeto pequeno de Lua e escrever uma ferramenta de transformação simples que converterá sua sintaxe de chaves em lua real.

Deseja + = de alguma forma? Isso também é facilmente algo que você pode fazer em um sistema de pré-processamento. Basta transformar instruções do formulário expr1 += expr2em expr1 = expr1 + expr2.

Concedido, você terá que encontrar uma maneira de detectar se um par de chaves representa uma tabela ou um do/endpar. E você tem que ligar o seu sistema de pré-processamento na Lua, substituindo dofile, loadstringe outras funções padrão biblioteca Lua. Mas tudo é factível.

Se pequenos problemas como esse são da sua preocupação, e você está muito ligado a um estilo de programação para mudar apenas como codifica (nota: geralmente é uma qualidade terrível de se ter como programador), essa é uma alternativa muito mais viável do que simplesmente escrevendo seu próprio idioma. Isso levaria talvez duas semanas no máximo . Compare isso com os anos que seriam gastos em um idioma adequado, com rico suporte à depuração e similares.

Se seus problemas forem maiores que isso (globais são o padrão, exigindo que você use em localqualquer lugar), alguns deles poderão ser gerenciados (simplesmente faça da declaração de novo global um erro, através do uso de ambientes e meta-tabelas alterados). Se você odeia funções como objetos de primeira classe, corotinas, coleta de lixo ou outros elementos básicos de Lua ... bem, então, você está criando um inferno;)

E se você realmente, realmente quero ser incondicional sobre isso, você pode escrever seu próprio idioma que você compilar em Lua. Portanto, você poderá pelo menos aproveitar o muito bem testado tempo de execução de Lua, a excepcional API de Lua e outros recursos básicos de Lua, todos da sua linguagem! Lua. Isso levará tempo, mas ainda não serão os anos que você gastaria em outra coisa.


Para mim, parece que eu poderia apenas codificar as funções se usasse Lua. Parece que estou apenas movendo código.
Skiperic

1
@ skiperic: Eu não sei o que você quer dizer com isso. Você pode dar um exemplo?
Nicol Bolas

Veja a resposta de Laurent acima.
Skiperic

2
@ skiperic: Isso realmente não explica o que você está preocupado. Você pode codificar em Lua? Sim. E o problema é ...?
Nicol Bolas

1
@BartekBanachewicz: Mesmo aceitando ser uma API C, ainda é superior a muitas APIs de script baseadas em C ++ que eu já vi. É a única API de script que eu consideraria realmente usar bruto , sem um fichário automatizado de algum tipo.
Nicol Bolas

3

Para complementar as outras respostas, essa não é uma opção estritamente binária. Dentro de uma linguagem de script existente, você também pode criar seu próprio idioma específico do domínio . As vantagens dessa abordagem são:

  • Na verdade, você não precisa mexer com gramáticas, analisadores, implementadores de editores personalizados etc.
  • Você está obtendo o maior benefício da implementação de uma linguagem de script especializada, ou seja, uma abstração adicional, específica para o seu jogo.
  • vs. homebrew: os usuários que estão familiarizados com a linguagem de script de sua escolha poderão usar imediatamente sua DSL.
  • vs. linguagem existente: os usuários não familiarizados com a linguagem de script precisarão apenas do conhecimento da DSL para modificar seu jogo.

A principal desvantagem é que você projetaria o DSL com as restrições da sua linguagem "base".


2

Ele pode fazer sentido, dependendo da mecânica do seu jogo. Alguns jogos com mecânica bastante simples podem usar uma linguagem interpretada para se salvar de uma codificação Lua / Python muito complicada, mas a economia de complexidade pode não valer muito. Por exemplo, um desses jogos da Interactive Novel poderia facilmente usar um mecanismo de script personalizado.

Se o seu jogo envolve um mecanismo de física, vários componentes do jogo e uma complexidade variável de personagens e habilidades, você definitivamente deve considerar procurar outras linguagens de script existentes, para não se esforçar para adicionar os recursos necessários ao seu personalizado ou corrigir erros com isto. Embora Lua seja provavelmente o mais rápido, há muitos outros que você pode gostar mais pela sintaxe deles, e muitos deles se gabam da facilidade com que se integram ao C. Python, Ruby e Angelscript. (Sinta-se livre para mencionar outras pessoas nos comentários)

Se você garantir que essas linguagens sejam usadas apenas para "controle lógico" (ou seja, lidar com um caso de colisão específico para certos tipos de objetos, como o dispositivo de explosão de chamas tocando um bloco de gelo), o desempenho dificilmente será um problema. Obviamente, por outro lado, se você os usar para obter mais códigos de rotina (criando um algoritmo de verificação de colisão personalizado que execute cada quadro), é mais provável que isso atrapalhe.


1
Lua também é uma linguagem de script muito popular no desenvolvimento de jogos.
Philipp

Sim, Lua é usada em todo o lugar, mas o OP notou que ele realmente não gostou muito. As preferências do estilo de codificação podem ser importantes.
Katana314

1
" Por exemplo, um desses jogos da Interactive Novel poderia facilmente usar um mecanismo de script personalizado. " Você obviamente não viu o Inform . Realmente, mesmo para aventuras de texto, não há sentido em criar seu próprio idioma.
Nicol Bolas

1
@ Katana314: "As preferências do estilo de codificação podem ser importantes. " Honestamente, o mundo ficaria melhor se os programadores saíssem do "estilo de codificação". Todos nós seríamos melhores programadores se parássemos de pensar que <inserir idioma preferido aqui> era fundamentalmente melhor do que <inserir idioma preferido aqui> de todos os outros. Usar linguagens que você talvez não goste da sintaxe do personagem cria e ajuda a evitar esse tipo de pensamento de bug.
Nicol Bolas

1

Eu digo, vá em frente. Em um currículo, seria uma demonstração extra de habilidade. Porém, lembre-se de que você precisa dessa habilidade primeiro. Não vai ser fácil, vai ser bem difícil. Existem livros sobre o assunto e tutoriais on-line também, mas, no final das contas, tudo se resume a você e sua compreensão de como funciona um compilador e como o código é analisado e traduzido.

Faça com que você comece com simplicidade, teste com frequência e mantenha o ideal. Mas lembre-se sempre, LUA está lá para você.


1
Acho que a pergunta aqui é se o objetivo é criar um jogo ou criar algo que pareça bom em um currículo.
Tridus
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.