"Eka é invisível", você diz, "o seu jogo não está entre os 100 melhores, por isso não é seguro". O mesmo é verdade. Porém, ao longo do ano de desenvolvimento do Protolife, adquirimos alguma experiência que podemos compartilhar com o futuro igrodelov em potencial. Os veteranos da indústria, receio, não encontrarão nada interessante para si. Mas talvez pelo menos se divirta com o coração.
Que tipo de jogo é esse? E quem somos nós?
Somos uma equipe de três pessoas (
GRaAL ,
A333 ,
icxon ), pela vontade do destino chamada Girafa Vulcânica, sem nenhuma intenção. Nós trabalhamos juntos por um longo tempo, nós três participamos do
Ludum Dare (competição de criação de jogos de fim de semana) e uma vez decidimos trazer para lançar
um de nossos artesanatos chamado Protolife.
Em resumo: esta é uma defesa de torre incomum, onde você tem que executar um cursor de herói e construir uma defesa de blocos contra a biomassa vermelha em constante crescimento.
Dos comentários ao artigo preliminar:
icxon : você precisa escrever um pouco sobre a jogabilidade primeiro. E então algumas capturas de tela nas quais o rábano entende o que está acontecendo
Se você pintar com mais detalhes, o que há no jogo:
- Há um conjunto de níveis, em cada nível existe a nossa base e o nosso avatar - um construtor de robôs.
- Parte do nível é preenchida com biomassa crescente vermelha que vomita toneladas de multidões.
- Mobs, é claro, correm para a base e tentam esmagá-la. E estamos construindo uma defesa contra as torres e não estamos deixando que isso seja feito.
"Mas o que é tão incomum?" - você pergunta. E as principais diferenças da maioria das defesas de torre são as seguintes:
- Controlamos o robô de construção diretamente a partir das teclas, ou seja, você deve se apressar manualmente sobre o nível e ter tempo para construir / reparar tudo.
- Tudo o que o robô pode fazer é construir e desmontar os blocos azuis. Um desses blocos não serve para nada, mas vários blocos dispostos de acordo com um determinado padrão se transformam em uma estrutura útil. Exemplos de modelos:
- Padrão 1: uma arma simples
- Padrão 2: parede
- Padrão 3: Arma AA. aqui você tem que usar também cristais amarelos, que já são extraídos mais difíceis
- Modelo 4: metralhadora
E o jogo continua: corremos, construímos, obtemos uma resposta, reparamos rapidamente. A visualização direta do processo de desenvolvimento do jogo é obtida.
Mas esse jogo não deu certo imediatamente. Em abril de 2017, no Ludum Dare 38, era assim:
Se você não prestar atenção à diferença na programação, parece que pouco mudou. Já na versão LD havia um construtor de cursor, a construção de torres a partir de blocos e o confronto com a biomassa vermelha. Deixamos porque funcionou e as pessoas gostaram.
Mas, de fato, muita coisa mudou sob o capô, além da concentração de grafônio por pixel quadrado. No caminho de um ano, tivemos que tomar várias decisões - jogabilidade, técnica, organização e até marketing. Alguns foram bem sucedidos, outros não.
Eu gostaria de contar sobre essas decisões.
Farei uma reserva imediatamente - provavelmente haverá vários artigos, porque Se você começar a cavar, sai muito material. No final deste artigo, você encontrará uma pequena pesquisa - quais tópicos seriam mais interessantes para você. Bem, links para o jogo em si também.
Uma história chata de criação.
Não acho que alguém esteja realmente interessado em como o jogo foi pensado, então vou removê-lo sob o spoiler.
De alguma forma, Conway, Matheson e Petri entraram no bar ...E o barman diz: indefinido não é uma função.
Na véspera do LD38, ficou terrível: o nosso colega e o único artista A333 voará todo o LD sobre o Atlântico e não poderá nos ajudar. Portanto, era necessário tornar o jogo tão pouco exigente quanto ao cronograma com as forças restantes.
O tema, a propósito, era "mundo pequeno". E então, durante o brainstorm, tudo foi mais ou menos assim:
- Não há artista - os gráficos são simples, primitivos
- Mundo pequeno - tamanho pequeno, ou talvez algo microscópico, como todos os tipos de germes
- Micróbios são um tipo de micro-vida.
- E a vida é um autômato celular. Bem, células em todos os sentidos. Deixe o jogador lutar com uma máquina celular contra outra máquina celular.
- Poked Conway Life - não é bom. Um jogador que é novo nas regras da máquina provavelmente criará algo que será destruído. É muito difícil de controlar. Deixe apenas o adversário seguir as regras da vida, e construiremos estruturas ordenadas.
- ... mas então o inimigo se autodestrói de vez em quando. Ok, vamos ajustar as regras para ele. Deixe crescer apenas, mas precisamos destruí-lo.
- Então, nós já temos: os glóbulos vermelhos do inimigo, que estão apenas crescendo, e os azuis, que nos construímos de acordo com os padrões dados. Construiremos torres e muros, ou seja, Acontece uma defesa de torre. Para variar, ainda não existem inimigos em movimento suficientes (mobs).
- Um dia antes de reler novamente "Sou uma lenda", de Matheson. Assim, o personagem principal à noite mantém o cerco dos vampiros e, durante o dia, quando os vampiros estão inativos, restaura a defesa e também expande a esfera de influência. Parecia um bom elemento de jogabilidade, então as fases do dia e da noite apareceram no jogo. À noite, as células inimigas compartilhavam e
marcavam casas, multidões rastejadas, durante o dia - tudo estava quieto, era possível contra-atacar.
- Chame nossos pixels coloridos de “microorganismos” e empurre-os em uma arena redonda - uma placa de Petri.
- Tomamos nosso mecanismo Phaser.js favorito ...
- ... e 31º lugar no nosso bolso
Aqui está uma história, não muito interessante, como eu avisei.
"Mas Alexei, o que diabos você escreveu então?" Pergunta razoável. O fato é que quase o primeiro comentário sobre o jogo soou como “lol, todos vocês roubaram o Creeper World”. Depois de ler o jogo muito mais tarde, o próprio LD, entendo por que as pessoas pensam assim. Mas ainda um pouco triste.
Se, de repente, você se sentir insultado por ter passado algum tempo com esse assunto,
como consolo, escreva-me o código PM "coisas chatas" no PM, e eu lhe enviarei uma das 10 chaves, se ainda não tiver terminado. Infelizmente, as chaves também terminaram.
Escolhendo um jogo para implementação completa
Como costuma acontecer, uma vez que todos pensávamos em nós três - mas é hora de tentar fazer um jogo completo. Muitas vezes, nesta fase, algum tipo de conceito é retirado da cabeça, como um "jogo dos sonhos", e o trabalho está sendo feito com ele. E então, que sorte adivinhar com os desejos do público.
Nossa tarefa foi um pouco simplificada devido à presença de um pequeno "portfólio" em Ludum Dare. Vimos como as pessoas reagem a jogos diferentes e poderíamos comparar. Protolife teve a melhor resposta, foi elogiado pela originalidade e pela jogabilidade interessante - este é um nível zero de gráficos e apenas 4 níveis!
Além disso, o itch.io nos ajudou a tomar a decisão, sobre a qual publicamos nosso artesanato. Como se viu, há pessoas que acessam o itch.io para jogar na web. Alguns deles adoram o gênero de defesa de torre, e entre 5 e 10 pessoas entram (e ainda entram!) Para tocar aquele velho Protolife
todos os dias .
Estatísticas de chamadas antes do lançamento do jogo no SteamPode-se dizer que esta foi nossa primeira pesquisa de marketing. Pensamos e decidimos que uma "defesa de torre não-padrão" poderia disparar. Não existem tantas defesas da torre, muitas delas são semelhantes a duas gotas de água, e podemos nos destacar entre elas.
Olhando para o futuro, posso dizer que as táticas valeram a pena.
Dica não solicitada # 1: Melhor não aja cegamente. O "jogo dos sonhos" ideal em sua cabeça pode não ser necessário para ninguém. Se você não participa de todos os tipos de compotas, sempre faz sentido esboçar um protótipo de jogabilidade (!) E testá-lo em você, amigos e conhecidos.
Contra-Conselho: Se você não tem medo de que metade das pessoas jogue o "jogo dos sonhos", quem se importa? Faça isso! Talvez com sorte.
Motor: Não é a melhor solução
Fizemos a versão no Ludum Dare no mecanismo
Phaser.js . Nós conhecemos bem, conhecemos bem o javascript, os jogos na Web recebem mais feedback, é bastante conveniente e fácil de aprender - um conto de fadas, não um mecanismo.
E enfrentamos uma pergunta importante: trocar o motor ou deixar tudo como está?
A pergunta foi complicada. Nenhum de nós conhecia ou estudava outro mecanismo naquele momento. Passar um tempo estudando é uma coisa boa, mas foi possível perder todo o entusiasmo. E então - o que levar? Javascript - a única linguagem que todos conhecíamos, para usar o mecanismo C ++ / Java / C # - significa perder instantaneamente metade dos desenvolvedores. E os motores de nível Unity da época pareciam muito pesados para um "jogo 2D simples".
E então: já existe um jogo. Resta atualizar o grafeno, completar os níveis - e isso é tudo. Trabalhe por alguns meses. E depois estudar, reescrever ...
Em geral, decidimos ficar no Phaser.js. Pior ainda: decidimos permanecer na mesma base de código, ou seja, Crie um jogo em cima do protótipo Ludum Dare.
Dos comentários em um artigo preliminar
a333 : Desculpe, eu não tinha essa foto com uma muleta em vez da Torre Eiffel "
Dica não solicitada # 2: Nunca faça isso! Isto é especialmente verdade para a reutilização do protótipo. O código em atolamentos é sempre escrito de forma rápida e suja, sem levar em consideração o desenvolvimento futuro. Há uma muleta, há uma muleta, e agora você entende que está escrevendo o código legado imediatamente e imediatamente começa a sofrer com ele. Os protótipos devem ser lidos com atenção e depois gravados em / dev / null e reescritos, apenas já cheios e limpos.
Contra-aconselhamento: leve em consideração, porém, as características da psicologia. Acontece que o atraso em algumas semanas é suficiente para "esfriar". Melhor fazer um jogo com arquitetura ruim do que não fazer.
Dos comentários ao artigo preliminar:
A333 : Estou muito inclinado a esta opção. Até onde eu sei, é assim que a maioria dos jogos é feita, porque o tempo e o fusível desempenham um papel fundamental. Se você tiver a oportunidade de reescrever tudo de forma limpa em um novo mecanismo - bom, mas nem sempre é esse o caso. Não tenha medo de escrever rápido e sujo, lançar protótipos antigos, copiar e colar trechos de código e liberar zabago ... * sons de golpes e gemidos abafados *
Na verdade, qual é o problema do Phaser.js?
- O mecanismo, como você pode imaginar, é baseado na Web. Sabe como lançar um jogo na Web no Steam? É isso mesmo, divulgue-o no Chrome usando o nw.js ou o Electron. Eu acho que as desvantagens dessa abordagem não precisam ser explicadas.
- O desempenho do javascript é certamente muito bom, mas o código nativo seria executado mais rapidamente e você poderia economizar em correspondências.
- Controle de renderização muito fraco. A própria Phaser processa tudo e o faz muito bem, mas às vezes você deseja entrar no processo ou fazer alguma coisa no webGL por conta própria. Infelizmente, a única coisa que Phaser permite é aplicar o sombreador de fragmentos à tela como um todo ou a alguns sprites separados na tela, e também com moderação. Ele não permite trabalhar com o vértice shader (e de fato trabalhar com vértices), e muitas decisões no jogo com eles seriam muito mais fáceis.
- Problemas com um grande número de sprites (objetos ativos) na tela. Além disso, o "grande número" é de alguns milhares, não milhões. E o "objeto ativo" será até uma pedra mentirosa sem animações. Para cada tick, a Phaser percorre todos os objetos e faz sua própria magia phaser especial, eliminando o tempo da lógica do jogo.
Resolvemos muitos desses problemas ao longo do caminho, alguns não resolvidos até o final. É difícil julgar sem experiência com outros mecanismos, mas parece-me que qualquer outro mecanismo permitiria processar milhares de objetos do jogo sem truques infernais. No entanto, eu posso estar errado.
Guerra de estilos
Você ainda se lembra do "design original" da versão original do jogo?
Obviamente, ele tem seu próprio charme, mas não era adequado para um produto sério. Sim, e nosso artista acabou de voltar de uma viagem de negócios, o que ele deve fazer para ficar ocioso?
Ele não se sentou, tendo feito vários esboços de um possível desenho. A história preservou duas cadeiras de estilo, entre as quais uma tinha que fazer uma escolha.
Candidato 1: design minimalista. De fato - os mesmos "pixels", apenas mais simpáticos. Tudo é brilhante, contrastante. Parece decente, mas, digamos, sólido. No sentido de que um jogo parecido com este ficará bem em telefones celulares ou no VKontakte em algum lugar entre tetris e arkanoid. Mas de forma rápida e barata.
Candidato 2: realista, fantástico, duro. Aqui você já pode ver uma certa história, contexto. Inesperadamente, o contraste funciona não apenas em cores, mas também em formas - nossos edifícios são mais ordenados e quadrados, edifícios inimigos - redondos, de forma irregular.

Isso não quer dizer que hesitamos por muito tempo. Imaginamos qual das “capturas de tela” gostaríamos de exibir mais, e o primeiro candidato simplesmente não teve chance de sobreviver. Não tínhamos ideia do que teríamos para o enredo, onde tudo isso está acontecendo, o que está acontecendo - mas escolhemos a opção dois.
Obviamente, não há nada com o que comparar, mas parece-me que essa foi uma boa opção. Sim, teríamos completado a primeira opção mais rapidamente, seria menos exigente em desempenho e gráficos e provavelmente teria sido possível portá-la para telefones móveis.
Mas queríamos jogar a segunda opção.
Assim, os microorganismos e a placa de Petri foram substituídos por um planeta distante, robôs e um misterioso organismo alienígena.
Conselho banal não solicitado número 3: faça o que você quer jogar sozinho.
Contra-conselho: se você tiver 3 hipotecas e nenhum outro emprego, ninguém o culpará por fazer algo que vende bem, mas você deseja lavar os olhos e as mãos com sabão.
Biomassa agachada, verme à espreita
Mencionei o contraste de cores e formas, e se você comparar esse esboço e a versão final - o contraste só se intensificou. Compare - os quadrados dos nossos edifícios, os edifícios inimigos redondos e a redondeza geral da massa vermelha.
A propósito, a massa vermelha, como quase tudo no jogo, em algum lugar dentro da lógica do jogo se encaixa na grade da mesma maneira que os blocos. Mas ela parece ao mesmo tempo caótica, como se estivesse desamarrada da rede.
Ainda tenho uma
demonstração em que depurei a aparência da biomassa. Tudo é organizado da seguinte maneira: um "quadrado" condicional é preenchido e preenchido com círculos de tamanhos diferentes o mais densamente possível. Abaixo está um exemplo desse preenchimento. No próprio jogo, o preenchimento é mais denso (e, portanto, pior, legível).
Entre círculos, existem linhas - conexões. Se a biomassa precisar crescer em algumas células, são selecionados círculos adequados que se cruzam com as células necessárias, e o crescimento ocorre nelas.
Aqui está o que parece em movimento:
Dos comentários ao artigo preliminar:
icxon : a primeira vez que vejo essa demo, lol
No próprio jogo, tudo funciona exatamente da mesma maneira, exceto que todos os tamanhos, cores e velocidades são ajustados pelo nosso artista para parecer melhor.
Ah, parece que esqueci de dizer de onde veio exatamente essa decisão, como foram as etapas da discussão, os candidatos foram varridos ...
Mas não, eu não esqueci. Não havia nenhum. Inicialmente, planejamos fazer tudo como na versão LD, ou seja, crescimento por quadrados. Apenas uma noite fiquei entediado e desenhei esta demonstração para praticar. E os caras foram. Então eles fizeram.
Dica não solicitada nº 4: planos, planos, mas não tenha medo de tentar algo novo. A intuição pode lhe dizer uma boa decisão.
Contra-aconselhamento: se você já definiu uma data de lançamento e assinou um contrato com um editor - talvez não deva experimentar.
Animação de biomassa
Nos gifs acima, você pode notar a animação ociosa da biomassa - mesmo em repouso, respira intensamente, os botões vermelhos parecem abrir e fechar. Em um mundo ideal, seriam sprites com animação cuidadosamente desenhada pelo artista, organizadas no mesmo padrão com círculos. Na realidade, esses seriam milhares de objetos de jogo que o Phaser.js simplesmente não poderia manipular. E isso já é um fato verificado - na versão com Ludum Dare, eu já encontrei freios infernais quando a biomassa encheu pelo menos metade do mapa, e não havia nenhuma animação ociosa lá.
Um shader vem em socorro, que gira na GPU e não ocupa um processador. Melhor ainda, se esse shader for realmente simples - ele não carregará muito a placa de vídeo.
O shader precisa, de alguma forma, dizer o que e como desenhá-lo. Quais são as maneiras de transferir informações para o shader:
- Código rígido no próprio código do sombreador. No nosso caso, ele não se encaixa, mas, em geral, às vezes essa opção também faz sentido.
- Via variáveis uniformes (são variáveis iguais para qualquer pixel da imagem)
- Via variáveis variáveis (variáveis interpoladas entre dois vértices)
- Através de texturas (codificando alguns valores com cores)
O método 3 pode ser útil para nós, mas no caso do Phaser.js, ele não está disponível para nós. Você não passa muito pelo uniforme (por exemplo, uma série de todos os círculos com seus raios não se encaixa nos uniformes - há restrições). A textura permanece.
O truque é este: primeiro desenho um estado (digamos, botões fechados) em azul:
Então o segundo estado (botões abertos) fica vermelho:
Se você adicioná-los, você terá uma bagunça roxa:
O sombreador, por outro lado, vê a textura, vê a hora atual e, com um certo período, mostra-nos que o estado "azul", depois o "vermelho", fluem suavemente entre eles. Bem, por si só, aplicar a paleta de cores desejada. Acontece assim:
Dos comentários ao artigo preliminar:
a333 : Ah, é assim que isso funciona ***
icxon : é legal porque eu ainda não entendo como funciona
O mesmo, mas com o exemplo de retângulos:
Textura:
Animação final:
A textura é atualizada apenas à medida que aumenta / diminui; o resto do tempo, a animação somente para gpu funciona.
Cuidado do jogador
No processo de desenvolvimento, tentamos não esquecer os jogadores que veem nosso jogo pela primeira vez. Não é tão simples quanto parece - depois de um tempo o olho fica embaçado e você começa a considerar óbvio tudo o que você, como desenvolvedor, já conhece.
Entendemos isso e, portanto, o primeiro teste beta já foi realizado 8 meses antes do lançamento - assim que tínhamos os 10 primeiros níveis e 40-50% do conteúdo pronto. Esse teste beta deu um excelente feedback de design de nível sobre o qual falarei na próxima vez. Ao mesmo tempo, aprendemos que nós mesmos tínhamos boas previsões de alguns pontos.
Situação: há uma base de jogadores que precisa ser defendida - sua destruição leva ao fracasso da missão. O jogador não monitora constantemente a base - ele assiste seu avatar de robô. E ele monitora constantemente - o ritmo do jogo é bastante rápido, não há muito tempo para ficar de pé e contemplar. Como resultado, nós, testadores, às vezes não percebemos o inimigo que estava atrás, bombardeando a base.Solução: primeiro, mostramos o dano à base em círculos concêntricos passando por meio mapa.Em segundo lugar, se a base estiver significativamente danificada, ela ataca independentemente, varrendo os inimigos, que são claramente visíveis e sonoros. Isso chama a atenção do jogador para o problema e dá tempo para agir.Situação: como em uma típica defesa de torre, os inimigos seguem um caminho batido. No entanto, essa rota nem sempre é adivinhada. E entender a rota é muito importante para uma defesa bem-sucedida: algumas torres disparam muito perto, e uma torre muito próxima será demolida pela próxima onda.Solução: tirar sangue depois de matar os inimigos. Depois de um tempo, um traço claro aparece no chão, no qual você pode se concentrar:Pergunta: mas, na verdade, por que a trilha batida? Você sabe como implementar o A *?Resposta: implementamos várias vezes :) experimentamos honestamente a IA inimiga. Tínhamos vermes espertos procurando a estrada, e lodos se esquivando de balas. Tornou-se impossível jogar. O jogador não conseguiu construir uma defesa eficaz e não pôde ficar feliz vendo como funciona. O prazer do jogo despencou. Isso não significa que inimigos "inteligentes" sejam ruins. Apenas para a mecânica escolhida - quando nossos edifícios são estáticos - esses inimigos não se encaixavam. Para "inimigos inteligentes", você precisa anexar uma metralhadora a um robô ou pernas a torres. E este é um jogo completamente diferente - não o que as pessoas gostaram no LD e no itchio.Dos comentários no artigo preliminar:
icxon : Mas ainda existem slimes. E eles ainda se esquivam do
GRaAL : pense um pouco na ficção
Eles realmente são, mas se esquivam muito mais preguiçosamente do que na versão originalSituação: o inimigo possui armas de longo alcance (morteiros) que podem estar fora da visibilidade do jogador. No começo, quase todo o campo está escondido atrás da neblina da guerra, por causa da qual a chegada de projéteis inimigos poderia passar despercebida - eles voavam para fora da escuridão e imediatamente causavam danos. Se o jogador estava olhando para aquele momento na direção oposta, ele pode não entender o que aconteceu.Solução: um projétil voador é visível acima do nevoeiro da guerra. Isso dá ao jogador a oportunidade de perceber a ameaça e agir.Falando de conchas. Vamos nos distrair dos problemas de jogabilidade-UX.Tratamento de colisão
Na versão LD dos objetos em movimento, não havia tantos - uma dúzia de balas e uma dúzia de worms a cada momento no tempo. Isso não foi suficiente no jogo. Para sentir o desafio, você teve que aumentar o número de oponentes e, ao mesmo tempo, dar ao jogador armas de fogo rápido para combater. Portanto, no jogo, essa situação não é incomum:Para todos os objetos do jogo, colisões devem ser consideradas. Balas colidem com minhocas, minhocas colidem com blocos e todas elas na tela - às vezes várias centenas. E as armas devem escolher seus alvos dentro do alcance. Se na versão LD pudéssemos interagir com todos os inimigos em busca de inimigos adequados, então aqui já estava começando a desacelerar.Em geral, esse problema tem soluções, em um habr encontrei frequentemente artigos sobre esse assunto (aqui está um deles ). Como temos uma grade lógica na tela e a maioria dos objetos ativos não excede o tamanho das células de jogo 2x2, decidimos usar essa grade para determinar colisões.Cada célula tem uma lista de objetos que estão nessa célula. Existem objetos estáticos (como blocos ou pedras) que ocupam exatamente uma célula como um todo e não se movem para lugar algum. E existem dinâmicas que se movem ao longo da grade, "fluindo" de uma célula para outra.Porque
um objeto pode estar localizado em algum lugar na borda de duas células (embora seu centro esteja claramente dentro de apenas uma); então, quando as colisões são levadas em consideração, todas as células vizinhas são examinadas. I.e.
pegamos um marcador com as coordenadas X, Y e vemos o que está nas células (X, Y), (X + 1, Y), (X-1, Y), (X, Y + 1), (X, Y -1). Se houver objetos com os quais o marcador possa interagir, para cada um deles exatamente a colisão será calculada com base na forma e no tamanho.Para não se levantar duas vezes, a mesma grade é usada para selecionar alvos pelas torres. Após a criação, a torre "assina" determinadas células da grade. Se algo que pode ser atingido entrar na gaiola, a torre recebe uma notificação (e geralmente depois disso é disparada). Assim, se mil inimigos se arrastarem obviamente para longe da torre, a torre não perderá tempo contando a distância até eles.Se o mapa for grande, as células na grade também se tornarão muitas e todas as atualizações e verificações começarão a demorar mais tempo. Além disso, os problemas começam se houver prédios / unidades do tamanho de várias células - para eles, é necessário verificar mais células.Para nivelar esses momentos, colocamos uma grande, 16x16 células de tamanho, em cima da malha fina. Tudo é considerado o mesmo para ela, e é usado para filtrar rapidamente situações em que não há nada no raio de várias células ao redor de objetos e colisões não podem ser verificadas.Links e pesquisas prometidos
O artigo já era bastante longo, e Deus proibiu minha lista de tópicos em um caderno de anotações diminuiu em um quarto. Diga-me, o que você gostaria de ouvir no próximo artigo? Você pode votar em alguns pontos.Bem, se de repente houver alguma pergunta específica sobre como é feito ou por que é feito - escreva nos comentários. Responderemos se lembrarmos :)Links para o jogo:Obrigado a todos pela atenção.