Não tenho certeza se ele se encaixa no escopo desta comunidade ou deve ir para Stackoverflow.
Vamos supor que eu queira que meu jogo seja facilmente extensível em sua essência, ou seja, eu quero que muitas pessoas, mesmo sem um conhecimento decente de programação, sejam capazes de não apenas ajustar as regras existentes, mas até adicionar mecânicas de jogo totalmente novas. Eu não sou um bom programador, mas estou pronto para aprender, só preciso de algumas instruções e garantia de que isso pode ser feito.
O que eu pensei é se é possível / viável implementar de algum modo a mecânica do jogo separadamente do código do utilitário principal? Quero dizer, para jogos de mesa, temos aqueles livros de regras que não contêm algoritmos reais de todas as ações, mas descrevem alguns protocolos e limites, referenciando fortemente o contexto de cada um desses itens. É possível fazer algo semelhante ao jogo para PC, como descrever todas as regras em um nível muito alto, facilmente legível (e alterável) por uma linguagem de programação humana, que é então "consumida" e analisada pelo código do utilitário em um instância de trabalho da mecânica de jogos?
Parece realmente que preciso escrever minha própria linguagem e um compilador))) o que não poderei fazer, é claro. Mas pode haver uma abordagem mais fácil para o problema?
FYI: minha linguagem de escolha para o código do utilitário será Python 3.x
fonte
Respostas:
De um modo geral, a facilidade com que qualquer sistema pode ser estendido depende do grau em que seus subsistemas estão acoplados de maneira firme ou vaga . Normalmente, quanto mais fracamente acoplados são os subsistemas, mais fácil é modificá-los à medida que são isolados e não necessariamente exigem uma compreensão completa do sistema como um todo.
Porém, nada é gratuito - esse sistema normalmente requer mais recursos (várias combinações de tempo, dinheiro e habilidade) para ser construído. O grau de extensibilidade que você descreveu me parece estar diretamente em desacordo com o nível de habilidade que você atribuiu a si mesmo. Isso pode ser feito, mas criar software como você descreveu é uma tarefa muito desafiadora.
As coisas mais próximas que eu conheço são Vassal (que é muito mais programático do que você descreveu), ou fazer um mod para o Tabletop Simulator (que depende principalmente da interação humana para interpretar e aplicar as regras do jogo).
fonte
Isso é absolutamente possível. Uma maneira usada frequentemente em jogos é o script Lua .
Do artigo vinculado:
Muitos jogos usam Lua. (Eu vincularia, mas a reputação de novos usuários está limitando minha contagem de links.)
Os scripts Lua podem ser compilados em tempo de execução. Isso significa que eles podem (por exemplo) ser arquivos de texto no diretório "scripts" do seu jogo, facilmente editáveis por um modder. Seu jogo os carrega e os executa.
Eu vi scripts Lua definir as propriedades das unidades do jogo. Aqui está um exemplo aleatório da TA Spring.
Mas você deseja "descrever todas as regras". Isso é possível em teoria, pois Lua é uma linguagem completa, mas o problema é que você precisa ser suficientemente presciente para que o código principal do jogo saiba procurar scripts para estender seu comportamento.
Por exemplo, você pode desenvolver um jogo de cartas que saiba procurar cards em um diretório "scripts / cards". Isso é ótimo para adicionar novos cartões ou editar os existentes. Mas se você quiser expandir seu jogo mais tarde para incluir miniaturas em uma grade, terá que editar o código principal - nenhuma quantidade de mexer com Lua o levará lá por conta própria.
Observe: eu trago o Lua porque sei que ele é comumente usado tanto em jogos quanto em software para personalização. Não estou sugerindo que seja a única solução, nem a melhor para as necessidades do interlocutor.
fonte
Há um continuum de abordagens e se alguma delas vale a pena, dependerá exatamente do que você está tentando fazer. Especificamente, quanto controle você deseja oferecer ao tweaker?
No extremo extremo do controle, você pode simplesmente deixar o tweaker modificar o código de todo o jogo. Nesse ponto, você essencialmente publicaria o código do utilitário e pelo menos um exemplo de como usá-lo. Um tweaker pode usar tanto ou pouco código quanto quiser.
Uma abordagem que ofereça um pouco menos de controle seria "congelar" seu código de utilidade (digamos, compilando-o de antemão) e deixar apenas os tweakers preencherem funções específicas (retornos de chamada), restringindo o que eles podem fazer. Dependendo do que você deseja fazer, essa abordagem pode assumir várias formas. Um método comum seria colocar toda a parte da exibição no código utilitário / principal e toda a mecânica na parte ajustável. Ou você pode manter algumas mecânicas na parte "congelada" porque é improvável que os jogadores as alterem ou torná-las mutáveis é muito complicado.
Na extremidade de baixo controle do continuum, apenas os tweakers alteram os valores dentro de um intervalo fixo. Um arquivo de dados que permite selecionar as cores das coisas dentro do jogo seria um exemplo. No entanto, você pode usar essa abordagem e ainda oferecer muita personalização. Seria possível definir uma seleção de funções e permitir que os tweakers os compusessem para criar os retornos de chamada da abordagem anterior, mas não permitindo que eles definissem novos. Ou talvez você pule a parte da composição e apenas ofereça uma seleção finita.
Os detalhes de todas essas abordagens e qual deles se encaixa no seu caso de uso depende de que tipo de jogo básico você deseja fazer e de quanto controle deseja abandonar. Observe que os jogos comerciais geralmente usam apenas o segundo e o terceiro método, porque o primeiro permite que os jogadores façam jogos totalmente separados, o que introduz problemas complicados de licenciamento. Observe que, como essas abordagens formam um continuum, a segunda abordagem também pode introduzir esses problemas.
fonte
É absolutamente possível separar as regras do sistema do código que as aplica. Prefiro estruturar meu código dessa maneira para projetos complexos, pois facilita a adição de novas regras ou a alteração posterior das regras sem introduzir erros no sistema subjacente. E os erros em um mecanismo de regras são encontrados mais rapidamente do que os erros em um sistema em que as regras e outros códigos são misturados muito alto, porque o mesmo mecanismo de regras é usado repetidamente por todas as regras.
Se vale a pena, depende da complexidade do sistema. Como se eu não me importasse com o Pac-Man, mas não conseguia imaginar escrever Dwarf Fortress de outra maneira.
fonte
É definitivamente viável. Se vale a pena, depende de seus objetivos.
Você não precisa inventar sua própria linguagem ou escrever um compilador para fazer isso funcionar.
Se você deseja que seu jogo seja facilmente extensível, provavelmente é uma boa ideia.
Provavelmente, é mais trabalhoso para você, pelo menos a curto prazo, criar sistemas compreensíveis e facilitar a modificação.
Um jogo que faz isso é o Rimworld (não tenho afiliação) e você pode ver e aprender como eles fizeram, basicamente colocando muitos dados e mecânicos de jogos em arquivos XML que estão nas pastas do jogo para qualquer um ver e modificar. O núcleo / mecanismo do jogo foi criado usando o Unity.
Há também a possibilidade de estender o jogo ainda mais / mais profundamente por meio da codificação real, eu sei menos sobre isso, mas você pode aprender olhando no fórum de mods.
A possibilidade de modificar torna o jogo mais interessante para muitas pessoas e acho que contribuiu muito para o seu sucesso. Ele também permite que os desenvolvedores tragam qualquer conteúdo modificado que desejem para o jogo principal e, de certa forma, que acelere o desenvolvimento e melhore o jogo, pois eles recebem assistência de muitas pessoas e podem decidir aceitar coisas com base em o que é popular, o que parece funcionar etc.
E, é claro, especialmente para um pequeno estúdio independente, eles têm centenas de pessoas criando idéias e testando-as para elas, o que é muito trabalho que elas não poderiam fazer por si mesmas, nem provavelmente contratam pessoas para fazer.
fonte
Você pode querer examinar o Design Orientado a Objetos . Python tem um bom suporte para isso.
Livros grossos são escritos sobre isso, o que pode ser assustador quando você é novo, mas os princípios principais são bastante fáceis.
O ponto principal é apenas que você identifica com que tipo de objetos está trabalhando. Você não diz que tipo de jogo está pensando, mas coisas como Jogador, Monstro, Item, Equipamento, Arma, Armadura e outros são objetos típicos.
Se você deseja diferentes tipos de jogos, provavelmente desejará um objeto de Jogo que cuide da condição de vitória e tal. Talvez um objeto Map também?
Às vezes, não está claro se algo merece ser um objeto ou não, por exemplo, danos. Se você não danificar um objeto, o código será mais simples, mas torná-lo um objeto facilita a personalização.
Subclassificação: Armas e Armaduras são Equipamentos. Equipamentos são itens. Provavelmente existem outros tipos de itens. Você provavelmente achará útil definir um Combatente de classe do qual jogadores e monstros sejam subclasses.
A idéia é que, por exemplo, as armas terão muitas coisas em comum com todos os outros tipos de itens, elas terão peso, tamanho e outras propriedades assim.
Portanto, a subclasse fornece uma maneira de dizer que "as armas são como outros itens, mas além disso você pode manejá-los, eles afetam o dano que você causa, etc. etc."
A subclasse também permite que seus criadores de mods digam "Meu novo tipo de arma é exatamente como as armas padrão, exceto que ..."
Então você tem que decidir qual objeto é responsável por quê. Isso não é tão fácil quanto parece e você deve pensar um pouco sobre isso. Fazer escolhas erradas não afetará muito o jogo básico, mas dificultará a personalização.
Contanto que você esteja apenas mexendo sozinho, você pode mudar as coisas, mas no momento em que lança algo ao público, fazer alterações se torna muito mais difícil! As pessoas farão mods que dependem das coisas serem exatamente como são agora. Até insetos. As pessoas escreverão mods que dependem de bugs que permanecem no código. Se você mudar as coisas, esses mods irão quebrar e lynch mobs aparecerão em sua casa.
Por exemplo:
Um jogador empunhando uma arma ataca um monstro usando várias armaduras. Isso ocorre em um modo de jogo específico e em um determinado mapa.
Ambos os Combatentes podem ter Habilidades como Golpe Crítico e Esquiva.
Agora, qual objeto é responsável por quê?
Não existe uma resposta certa para isso. Depende muito do tipo de personalização que você deseja permitir.
Se você nunca chamar um objeto (por exemplo, o Mapa), esse objeto não poderá alterar o ataque de forma alguma.
Depois de tomar todas essas decisões, documente-as . Escreva um "Manual do Modders" que lista exatamente quais métodos modáveis cada objeto possui, quais parâmetros eles usam, quais devem retornar e assim por diante ...
Boa sorte!
fonte
Uma maneira simples de obter algum suporte básico para isso seria separar a maioria dos valores numéricos em um ou mais arquivos de texto separados para permitir que indivíduos interessados os ajustem no esquecimento.
Por exemplo, você mencionou jogos de mesa; se você teve um jogo baseado em D&D, pode ter um
weapon_damage
arquivo contendo linhas comoBattleaxe: 1d12
. O código do seu utilitário leria esse arquivo e, sempre que um dano fosse causado peloBattleaxe
seu, ogenerate a number from 1-12, 1 time(s)
acrescentaria. Ajustar a linha para lerBattleaxe: 4d6
ogenerate a number from 1-6, 4 time(s)
adicionaria. Da mesma forma, você pode ter uma pastaCreatures
e, dentro, um arquivo para cada criatura, incluindo linhas comoAC: 12
; adicionar novos arquivos a essa pasta criaria novas criaturas. Poderia até ser feito para classes de personagens, tipos de terreno, muitas coisas.Esse estilo de personalização sem código ainda pode ser muito poderoso e abranger muitas partes do seu jogo. No entanto, isso realmente não permite que um usuário faça alterações que você não especificou explicitamente. Por exemplo, você pode permitir
Sneak Attack: [damage]
que seja dada a qualquer Criatura ou Classe para adicionar[damage]
a qualquer ataque que atenda às condições de um Ataque Furtivo. Você pode até fornecer maneiras de alterar quais são as condições, como "sempre que você atacar furtivamente" ou "sempre que estiver flanqueando" ou "sempre que tiver vantagem". No entanto, se um usuário decidir que deseja que os ataques furtivos sejam "Quando você faz um teste de ataque, também pode fazer furtividade contra a percepção do alvo. Se ambos os testes forem bem-sucedidos, adicione o dano de Ataque furtivo"Se você deseja que um usuário possa adicionar um comportamento completamente novo ao jogo sem precisar de habilidades de codificação no mesmo nível que o desenvolvedor, então, como as pessoas mencionaram, você está procurando essencialmente criar um mecanismo de jogo ou uma linguagem de programação separada. Para modificações que não exigem conhecimento de codificação, os arquivos de dados baseados em texto e as estruturas de pastas ainda podem fornecer muitas opções. Se você quiser que os usuários modifiquem mais do que isso, precisará solicitar que eles aprendam ou conheçam uma linguagem de programação.
fonte
[Sou desenvolvedor de software há décadas, mas sem experiência em desenvolvimento de jogos, talvez a indústria de jogos adote abordagens diferentes, talvez por boas razões ...]
Sua abordagem faz absolutamente sentido para mim. O núcleo fornece as funcionalidades básicas em que a mecânica e as regras se baseiam, por isso é uma API que deve ser usada pelos componentes de nível superior.
E ao projetar uma API, minha orientação favorita é criar a linguagem na qual você deseja expressar seu código de nível superior (é claro, sem as limitações de sintaxe da sua linguagem de programação).
Portanto, uma boa abordagem seria escrever algumas regras e mecânicas hipotéticas da maneira que você gostaria que fossem expressas (com a sintaxe do Python, é claro), descobrindo assim o que você deseja que a API principal forneça às regras e mecânicas camadas.
E, é claro, eu recomendo dar uma olhada nas instalações de script dos jogos existentes para ter uma idéia do que eles fazem.
fonte