Por que o MVC e o TDD não são mais empregados na arquitetura de jogos? [fechadas]

155

Eu prefácio isso dizendo que não procurei uma quantidade enorme de fontes de jogos nem construí muito na maneira de jogos.

Mas, ao tentar empregar práticas de codificação 'corporativas' em aplicativos da Web, olhar seriamente para o código-fonte do jogo me machuca: "O que essa lógica de visão está fazendo com a lógica de negócios? Isso precisa de refatoração ... o mesmo acontece com refatoração, refatoração e refatoração" "

Isso me preocupa, já que estou prestes a iniciar um projeto de jogo, e não tenho certeza se a tentativa de mvc / tdd o processo dev nos atrapalhará ou nos ajudará, pois não vejo muitos exemplos de jogos que usam isso. ou muita pressão por melhores práticas arquitetônicas na comunidade.

O que se segue é um extrato de um ótimo artigo sobre jogos de prototipagem , embora, para mim, parecesse exatamente a atitude que muitos desenvolvedores de jogos parecem usar ao escrever o código do jogo de produção:

Erro # 4: Construindo um sistema, não um jogo

... Se você se encontrar trabalhando em algo que não está avançando diretamente, pare aí. Como programadores, temos a tendência de tentar generalizar nosso código, torná-lo elegante e poder lidar com todas as situações. Achamos que uma coceira terrivelmente difícil não arranha, mas precisamos aprender como. Levei muitos anos para perceber que não é sobre o código, é sobre o jogo que você lança no final.

Não escreva um sistema elegante de componente de jogo, pule completamente o editor e conecte o estado no código, evite a loucura XML, baseada em dados e de análise automática, e apenas codifique a maldita coisa.

... Basta colocar as coisas na tela o mais rápido possível.

E nunca, jamais, use o argumento "se demorarmos um pouco mais e fizermos isso da maneira certa, podemos reutilizá-lo no jogo". SEMPRE.

é porque os jogos são (principalmente) orientados visualmente, por isso faz sentido que o código tenha um peso maior na visualização, portanto, quaisquer benefícios de mudar as coisas para modelos / controladores são bastante mínimos, então, por que se preocupar?

Ouvi o argumento de que o MVC introduz uma sobrecarga de desempenho, mas isso me parece uma otimização prematura e que havia problemas de desempenho mais importantes a serem resolvidos antes que você se preocupe com as sobrecargas do MVC (por exemplo, pipeline de renderização, algoritmos de IA, estrutura de dados passagem, etc).

A mesma coisa com relação ao TDD. Não é comum ver jogos empregando casos de teste, mas talvez isso se deva aos problemas de design acima (visão mista / empresa) e ao fato de ser difícil testar componentes visuais ou componentes que se baseiam em resultados probablísticos (por exemplo, operam em simulações físicas) )

Talvez eu esteja apenas olhando o código fonte errado, mas por que não vemos mais essas práticas "corporativas" empregadas no design de jogos? Os jogos são realmente tão diferentes em seus requisitos ou é um problema de pessoas / cultura (por exemplo, os desenvolvedores de jogos têm uma experiência diferente e, portanto, têm hábitos de codificação diferentes)?

timoxley
fonte

Respostas:

137

Como diz a citação, muitos programadores cometem o erro de (tentar) construir um sistema, não um jogo. Normalmente, esse sistema fica fora de controle até que seja tão complexo que, teoricamente, ele pode lidar com qualquer coisa, mas, na praticidade, tudo o que você tem é um grande pacote de códigos. Ou, mais frequentemente, antes mesmo de chegar ao estágio de trabalho, você fica tão envolvido em um código que não é executado que perde o foco (se você tivesse algum para começar) e a motivação (já que nada está realmente funcionando).

Protótipos e iteração tendem a funcionar muito melhor. No final, um ótimo design pode surgir, mas mais frequentemente algo mais simples e refinado sai dele. KISS e YAGNI vêm à mente.

Pessoalmente, acredito que precisa haver um equilíbrio. Se houver um mecanismo básico para o seu jogo, trabalhe nele. Você ainda precisa iterar, mas precisa refiná-lo. Dica: a organização do seu código não é um mecanismo básico do seu jogo.

Caso em questão: Peggle , da PopCap Games. A mecânica principal do jogo é a física da bola. Eles aperfeiçoaram! Tenho certeza de que eles passaram muito tempo se certificando de que era absolutamente perfeito, porque é o que faz o jogo. Mas, ao mesmo tempo, consigo imaginar totalmente um protótipo inicial de seu jogo que talvez apenas desenhe sprites na tela e faça algum tipo de detecção e salto de colisão mais primitivos, apenas para ver se a ideia do jogo é divertida. Então, uma vez que descobriram que atirar uma bola e assisti-la saltar pode realmente ser divertido, eles refinaram o movimento da bola. (tudo isso é apenas especulação, é claro)

Também depende de seus requisitos técnicos, que você deve definir desde o início (não do design do jogo, apenas dos requisitos técnicos). A plataforma em que o jogo é executado não deve mudar ou, se for permitido mudar, você precisa saber exatamente até que ponto planeja permitir que ele mude, nem mais nem menos. Design sobre isso. Se você está desenvolvendo um jogo para o OpenGL e não se importa com o DirectX, na verdade, não se importa. Isso significa que, se for mais conveniente que cada entidade se desenhe e não se preocupe com fábricas e outros padrões de design como esse, faça isso. Está tudo bem, porque atende aos requisitos. Você não precisa alterá-lo mais tarde, apesar do que diz a si mesmo. E realmente, pior cenário? Refatorar mais tarde., obter um jogo funcional em uma plataforma, mesmo que isso signifique que não pode ser executado simultaneamente e automaticamente na sua torradeira.

Design orientado a teste, no entanto, é um tópico mais opinativo. Eu acredito que os desenvolvedores de jogos devem fazer mais. Também acho que os desenvolvedores de jogos têm alguns dos cronogramas mais rigorosos e restritos, e pensam que não podem gastar tempo no TDD quando querem apenas começar o jogo. Além disso, novamente com a motivação, o TDD é muito mais lento e você vê muito menos um jogo em funcionamento (pelo menos no começo). Isso pode ter sérios efeitos negativos na motivação do programador.

Eu acho que também é apenas uma falta geral de conhecimento e prática. Também não acho que o TDD seja predominante em outras áreas, mas, como o desenvolvimento ágil, acho que está se espalhando. Você pode dizer que está adiantado (ou talvez não, conforme o caso daqui a anos). Mais importante que o TDD é o "RDD" - Desenvolvimento Orientado a Requisitos. Eu apenas inventei isso.Qual é o teu objetivo? Para fazer um jogo. Tudo o resto vem em segundo. Se você pode provar que o TDD aumenta a produtividade e ajuda as equipes a atingir prazos, não acha que todos o usariam? E talvez seja esse o caso. No momento, porém, nossa indústria está mais competitiva do que nunca, há prazos mais difíceis e mais cedo, e as coisas precisam funcionar. Trabalhadores da construção civil não constroem andaimes primeiro; eles estabelecem uma fundação, depois erguem algumas paredes e pisos e só então constroem pedaços seletivos de andaimes para realizar tarefas específicas que os andaimes tornam mais convenientes. Eu acho que o mesmo se aplica ao desenvolvimento de software.

Desculpe por um post tão longo. Espero que você tenha ganho um pouco de sabedoria com isso. Sou apenas um estudante, falando sobre minhas observações, com experiência muito limitada no setor, mas muita leitura de especialistas do setor. Então pegue minhas palavras com um grão de sal.

E ei, faça o que você acha que vai funcionar. Você sempre pode alterá-lo ou descartá-lo e começar de novo. Essa é a coisa legal de qualquer forma de engenharia; se a princípio você não conseguir, tente algo diferente. (ou algo assim :-P) Você não está derramando concreto; o software é maleável.


A propósito, eu venho fazendo esse mesmo tipo de pergunta e pesquisando esses tipos de princípios de design há algum tempo. Aqui estão algumas perguntas, aqui e no Stack Overflow, que você pode achar relevantes:

Ricket
fonte
32

Aqui está a minha resposta original para uma pergunta semelhante sobre SO há algum tempo, pelo menos no que diz respeito à parte MVC da sua pergunta:

Raramente é usado em jogos. Demorei um pouco para descobrir o porquê, mas eis os meus pensamentos:

O MVC existe para fazer uma distinção entre duas representações. O modelo é a representação abstrata de seus dados. É como a máquina vê o estado do seu aplicativo. O modo de exibição (e controladores) representa uma instanciação visível mais concreta desse sistema de uma maneira que é significativa para os seres humanos.

Na maioria dos aplicativos de negócios, esses dois mundos são bem diferentes. Por exemplo, o modelo de uma planilha é simplesmente uma grade de valores 2D. Ele não precisa pensar na largura das células em pixels, onde estão as barras de rolagem etc. Ao mesmo tempo, a exibição da planilha não sabe como os valores das células são calculados ou armazenados.

Em um jogo, esses dois mundos estão muito mais próximos um do outro. O mundo do jogo (modelo) é tipicamente um conjunto de entidades posicionadas em algum espaço virtual. A visualização do jogo também é um conjunto de entidades posicionadas em algum espaço virtual. Volumes limitados, animação, posição etc., todas as coisas que você consideraria parte da "visão" também são usadas diretamente pelo "modelo": a animação pode afetar a física e a IA, etc.

O resultado final é que a linha entre modelo e visão em um jogo seria arbitrária e não ajudaria: você acabaria duplicando muito estado entre eles.

Em vez disso, os jogos tendem a desacoplar as coisas ao longo dos limites do domínio: IA, física, áudio, renderização etc. serão mantidos o mais separados possível.

maravilhoso
fonte
20

Porque o MVC não se encaixa na arquitetura de um jogo. O fluxo de dados de um jogo é totalmente diferente do de um aplicativo de preço corporativo, porque não é direcionado a eventos e geralmente há um orçamento de milissegundos (muito) apertado para executar essas operações. Há muitas coisas que precisam acontecer em 16,6 milissegundos, por isso é mais benéfico ter um pipeline de dados 'fixo' e rígido que processa os dados necessários na tela exatamente nesse período.

Além disso, a separação está lá; na maioria das vezes, ele não é conectado da mesma maneira que o padrão MVC. Existe um mecanismo de renderização (View), manipulação de entrada do usuário (Controller) e o restante, como lógica de jogo, ai e física (Model). Pense nisso; se você está buscando a entrada do usuário, executando o ai e renderizando a imagem 60 vezes por segundo, por que você precisaria de um Observer entre o modelo e a visualização para informar o que mudou? Não interprete isso como eu dizendo que você não precisa do padrão Observer nos jogos, mas sim, nesse caso, você realmente não precisa. Você está fazendo todo esse trabalho, todos os quadros, de qualquer maneira.

Embora o TDD quase nunca seja usado em estúdios de desenvolvimento, usamos práticas ágeis para o desenvolvimento de software e o SCRUM parece ser a escolha popular pelo menos aqui na Europa. A razão é simples, as mudanças vêm de todos os lugares. Os artistas podem querer mais orçamento de textura, mundos maiores, mais árvores, enquanto os designers desejam uma história mais rica (mais conteúdo em disco), um mundo de streaming e os editores desejam que você termine no prazo e orçamento, e o departamento de marketing também. Além disso, o "estado da arte" continua mudando rapidamente.

Isso não significa que também não testamos, a maioria dos estúdios possui grandes departamentos de perguntas e respostas, executa vários testes de regressão e realiza testes de unidade regularmente. No entanto, quase não faz sentido fazer testes de unidade antecipadamente, porque grande parte dos bugs são relacionados a arte / gráficos (buracos nas malhas de colisão, texturas erradas, falha na profundidade do shader de campo) que os testes de unidade não podem cobrir. E, além do código de trabalho, o fator mais importante de qualquer jogo é que é divertido, e não há testes de unidade.

Lembre-se também de que no mundo dos console isso ainda é diferente, porque você está programando mais para o hardware do que para qualquer outra coisa. Isso geralmente (PS2 / PS3) significa que o fluxo dos dados é muito mais importante que o fluxo do código em quase todos os casos; devido a considerações de desempenho. O que anula o uso do TDD como uma ferramenta de arquitetura na maioria dos casos. Um bom código OOP geralmente possui um fluxo de dados incorreto, dificultando a vetorização e a paralelização.

Jasper Bekkers
fonte
13

Por que o MVC e o TDD não são mais empregados na arquitetura de jogos?

Aviso: opinião à frente.

O MVC não é usado (muito) porque:

  1. O MVC é uma abordagem relativamente nova e os jogos geralmente são criados com códigos antigos. A maioria das pessoas que cria aplicativos MVC os constrói do nada a cada vez. (Eu sei que o próprio MVC tem décadas; o que há de novo é o grande interesse nele, que veio essencialmente de aplicativos da web como o RoR). No software comercial em que trabalhei, baseado no código legado, também não havia uso para o MVC. É uma coisa da cultura, mas não é específica do jogo.
  2. MVC é essencialmente um padrão de GUI para programas orientados a eventos. Os jogos não são dominados por GUI nem orientados a eventos; portanto, a aplicabilidade não é tão grande quanto é para aplicativos da Web ou outros aplicativos baseados em formulário. O MVC é tipicamente o padrão Observador, com algumas funções bem conhecidas, e os jogos geralmente não têm o luxo de esperar para observar algo interessante - eles precisam atualizar tudo a cada quadro (ou alguma variação nisso), independentemente de alguém clicar ou não em algo .

Isso não quer dizer que os jogos não aprendam muito com o MVC. Eu sempre tento separar o modelo da vista nos jogos que faço. A idéia tradicional de a view e o controlador serem duas partes do mesmo objeto (widget) não funciona realmente, então você precisa ser um pouco mais abstrato sobre isso. Concordo com você que é improvável que o desempenho seja um problema real aqui. Se qualquer desempenho pode se beneficiar mantendo as coisas visuais e as lógicas separadas, pois isso é mais passível de armazenar em cache a coerência, o paralelismo etc.

TDD não é usado (muito) porque:

  1. É realmente estranho usar em jogos. Novamente, é bom para software orientado a eventos em que entradas e saídas saem e você pode comparar o que viu com o que esperava e marcar como correto. Para simulações com grandes quantidades de estado compartilhado, é significativamente mais complicado.
  2. Não há evidências indiscutíveis de que isso ajude alguma coisa. Muitas reivindicações e alguns números geralmente se baseiam em auto-relatórios e apelos à autoridade. Talvez ajude os programadores pobres a se tornarem medíocres, mas retém bons programadores. Talvez o tempo gasto escrevendo testes possa ser melhor gasto aprendendo os princípios do SOLID ou projetando a interface correta em primeiro lugar. Talvez seja uma falsa sensação de segurança ter testes aprovados sem nenhuma prova real de que você tenha testes suficientes para garantir que seu objeto faça a coisa certa.

Mais uma vez, como uma ressalva, acho que os testes de unidade são ótimos, mas não acho que "testar primeiro" seja benéfico ou sensato. Também não acho prático testar a simulação principal quando há tanto estado compartilhado mudando muitas vezes por segundo. Limito meus testes ao meu código de baixo nível e biblioteca, geralmente.

No entanto, como você provavelmente pode adivinhar, sou amplamente influenciado pelas "práticas de codificação" corporativas ", pois as empresas são conhecidas por ultrapassar prazos e orçamentos. "Desenvolvedores de jogos também!" Eu ouvi você dizer - bem, sim. Eu não acho que alguém realmente saiba a melhor maneira de desenvolver software no momento e não estou convencido de que a adoção de práticas organizadas no software convencional esteja a um passo das práticas mais livres do software de entretenimento. Na verdade, eu suspeito que é principalmente benéfico para aqueles que confiam em programadores Java de commodities, onde essas abordagens não são uma escada para subir a alturas maiores, mas uma rede de segurança para impedir que caiam muito baixo.

Kylotan
fonte
9

Como observa Kylotan, "nos jogos, você não pode tratar o aspecto da apresentação como um conceito destacável e substituível, como HTML e CSS, para aplicativos da web". Depois de criar alguns jogos usando um padrão MVC simples (não uma estrutura enorme), descobri o grande problema é que seu modelo precisa saber sobre sua visão. É muito provável que você precise usar dados de bitmap de sprite, dados de hitbox ou dados de geometria 3D de seus materiais de arte para ajudar a descobrir a detecção de colisão (ou outra tarefa semelhante). Isso significa que cada modelo precisa de uma referência à sua visualização, o que quebra o padrão clássico do MVC - por exemplo, você não pode mais criar uma nova visualização para um modelo existente etc.

O modelo de componente que você vê, por exemplo, no Unity3D, é a melhor maneira de organizar o código do jogo.

Iain
fonte
4

O MVC, em alguns níveis, já é usado no desenvolvimento de jogos. É imposto pelo sistema operacional, que possui interfaces diferentes para entrada e gráficos. A maioria dos jogos também possui mais algumas instâncias de MVC, por exemplo, separando a física e os segmentos de renderização e entrada. Isso funciona bem. A idéia moderna do MVC parece ser que ele deve ser repetido fracionariamente, até que ninguém mais possa entender o código. Jogos não fazem isso, felizmente.

O TDD não é usado porque raramente se sabe que um jogo "deveria fazer" antes de você repetir o protótipo várias vezes. Práticas do TDD, como teste contínuo ou teste de integração, são frequentemente usadas no desenvolvimento de jogos.


fonte
3

Os sistemas de jogos estão lentamente migrando para melhores práticas. Estruturas como o XNA fornecem uma visão para tornar o código mais generalizado / limpo, sem acrescentar muita sobrecarga no tempo de design ou execução. Mas, em geral, eu diria que os sistemas de jogo têm como objetivo otimizar a complexidade versus a velocidade de execução, mantendo um cronograma de desenvolvimento apertado e motivados. A aplicação de conceitos de engenharia de software e design de sistemas simplesmente não é a prioridade número 1 em um ambiente como esse.

Nos meus projetos pessoais de jogo, tento comentar o código ou, pelo menos, torná-lo legível, e montei sistemas que permitirão um pouco mais de flexibilidade mais tarde (ou seja, generalidade), tanto quanto possível, mas no final do dia, se você não avançou no jogo, simplesmente não é muito bom.

Também tipicamente quando você termina o jogo, você tem pelo menos 1000 idéias sobre como melhorar a mecânica subjacente, os sistemas principais, etc., de tal maneira que muito pouco desse código "reutilizável" será realmente seja utilizável. Durante o dia, trabalho em SE regularmente e, embora os sistemas em que trabalhamos sejam enormes, honestamente, acho que eles empalidecem em comparação com a complexidade dos jogos.

Deleter
fonte
2

Não tenho uma opinião particular do MVC fora do fato de que a visão é frequentemente separada da lógica pelo simples fato de que o loop de renderização está empacotando um monte de coisas para que algum hardware processe e esse não é o lugar onde você deseja "jogo" lógica "acontecendo simultaneamente. O "controlador" também é separado por hardware, mas infelizmente muitos, se não a maioria dos desenvolvedores de jogos, fazem trabalhos "interessantes" no manipulador de controladores. (OMI, o manipulador do controlador deve ler os botões e paus e criar uma "apresentação" para o jogo exibir, mas minha caixa de sabão não é tão forte.)

TDD, por outro lado, é algo sobre o qual tenho opiniões muito fortes. Isso apenas altera o desenvolvimento de maneira a produzir software mais fácil de construir. É mais difícil de fazer, sem dúvida. Obviamente, como é mais difícil de fazer, não está feito. Algumas pessoas reclamam que o TDD (ou, geralmente, o teste unitário) não tem valor porque "o jogo é o teste", mas o fato é que, no TDD, o teste é quase irrelevante. O objetivo do TDD é o design e a arquitetura do software que sai do processo.

Adotar o TDD realmente muda a abordagem de programação. Eu tinha alguns sentimentos sobre o que estava certo e o que estava errado antes de começar o caminho do TDD, mas quando entrei com os dois pés, realmente entendi muito mais sobre como as coisas que eu estava fazendo estavam ajudando ou impedindo o desenvolvimento futuro. . Na verdade, esse é o ponto por trás do post da sala de codificação, TDD sem o t .

De volta ao motivo pelo qual não é mais usado em jogos, além de difícil, faz com que as pessoas percebam que a maneira como sempre fizeram no passado desnecessariamente dificultou seus próprios trabalhos, e para os programadores, especialmente que é uma pílula amarga, mesmo para olhar, muito menos andorinha.

Estou convencido de que as pessoas que se recusam a aceitar o TDD simplesmente não querem ser melhores programadores. Eles já pensam que são "excelentes" em programação, design ou arquitetura, quando na verdade o código deles diz algo completamente diferente.

traço-tom-bang
fonte