sábado, 28 de setembro de 2013

Like a Boss! - Screenshot

E ae pessoal, blz?

É... trabalhar no mundo dos jogos né moleza não... pleno sabado e cá estou eu no escritório, trabalhando...

Bom, como a maioria deve ter percebido, eu sou programador, mas, é tão foda trabalhar no Like a Boss que eu nem sei por onde começar, quando tenho a chance de trabalhar nele... é tanta coisa que quero implementar, tanta coisa foda pra fazer...

Mas, tem tanta coisa nova no jogo que ainda não mostramos pra ninguém que decidi tirar um "teasershot" do jogo =P

"Reckless players... none may challenge the Skeleton King!" - by Eoric, the Skeleton King
Bom, é isso ai, hoje também inauguro o primeiro post pequeno do blog... hauhauah =P se eu conseguir amanha faço um post mais caprichado por aqui.

Abraços pessoal, bom resto de fim de semana!
Allan

quinta-feira, 26 de setembro de 2013

Unity - Traduzir o jogo para várias línguas

E ai pessoal, tudo bem?

Bom, infelizmente não tenho condições de escrever aqui todos os dias =( é trabalho d+ pra tempo d-, e também trivializa um pouco demais cada post já que eles viriam a falar de coisas muito pontuais...

Mas, hoje e ontem, por acaso, nós trabalhamos em uma coisa que pode ser interessante pra algumas pessoas: traduzir seu jogo para várias línguas!

"Ta me zuando que vou ter que traduzir pra grego 2x?"
Bom, não tem muito mais o que se dizer sobre isso! Usando Unity, existem porções de plugins para manejar fácil as línguas e não sei o que... nós aqui na Fire Horse não usamos nenhum deles (mas talvez devêssemos =P), nós criamos uma solução bem bobinha, mas que tem funcionado muito bem.

Até o momento todos os nossos jogos tiveram de ser no mínimo bilíngues, Commander Flag e Knights Trial tiveram de ser traduzidos para Inglês, Português e Espanhol devido á competição da Square Enix, até Ready, Eat, Fight! teve que ser traduzido para o Português pra colocarmos no ClickJogos. O único que esta sendo perdoado até o momento é o Like a Boss, mas já está sendo montado de forma que essa tradução seja fácil.

No entanto, o caso em que estamos trabalhando agora, e certamente o mais intenso deles... é o Level Up: Heroes of Neverfail. O nosso querido Cartoon Network, não feliz com Inglês, Português e Espanhol, as línguas presentes inicialmente no jogo... nos pediram pra traduzir o jogo também para Frances, Italiano, Russo, Turco e Árabe. Sim, Árabe -.-

Grafico (pouco racista) da globalização chegando no Reino Unido. Quanto mais línguas, melhor!
E desde o Commander Flag... nós usamos exatamente a mesma solução... uma classezinha que eu chamo de LanguageDictionary. Ela é tão idiota que é mais fácil colocar o código dela aqui que explicar o que ela faz.

Você pode adicionar quantos valores quiser no dicionário, 10, 100, 1000, conforme for necessário.
Viu que ridículo? Basicamente eu tenho um dicionario com chaves string e valores string... e onde eu precisar de um texto, eu simplesmente busco no meu dicionario pela chave, e mostro o valor. Não tem como ser mais simples que isso. Toda vez que o jogador troca de linguagem, eu zero o dicionário e coloco os novos valores. Então basicamente, em qualquer string do jogo, invés de escrever "Espada Legal" na mão, eu escrevo "cool-sword". Quando a cena for carregada, o script vai procurar la na minha lista global de variáveis pelo índice do dicionario com cool-sword, e se for em inglês, vai mostrar "Cool Sword", se for em português "Espada Legal", e o meu preferido, se for em árabe vai mostrar "السيف بارد"!

Olha que difícil que é usar o código acima... Se você jogar esse script num GameObject com um TextMesh, ele vai traduzir o TextMesh pra linguagem que estiver ativa com base a chave que você passar.
Claro, isso só serve pra tradução de palavras, mas e imagens? Bom, ai depende. Antes do jogo do Level Up, nós não usávamos nenhum plugin do tipo NGUI, EZGUI e não sei o que... era tudo na mão (na mão, mas não com a GUI do Unity, obviamente (PS: até sair o novo GUI do Unity, NÃO USE O GUI DO UNITY)), o que dificultava um pouco as coisas. Nós criávamos planos, com materiais e texturas. Logo, pra traduzir essas imagens, precisamos criar um dicionário também de string/string, só que ao invés de simplesmente passar o valor do dicionário pra uma caixa de texto, nós usávamos um Resources.Load(LanguageDictionary.stringList["chave"]). Dessa forma, no loading da cena, todas as imagens que precisavam ser trocadas para a língua desejada eram carregadas e jogadas na textura do plano.

Paralaxe de 4 profundidades... estrelinhas... levels abertos, travados... tudo com plano, que coisa bonita... (Commander Flag)
Hoje em dia nós ainda utilizamos o approach precário de criar planos na mão, mas em conjunto com o NGUI. Não usamos NGUI puro porquê por mais milagroso que seja o plugin (e sim, é MUITO bom), ele pode causar (e certamente causará) SÉRIOS problemas de desempenho no seu projeto. Não vou entrar em detalhes sobre isso, mas o negócio é que no NGUI as texturas das imagens não são referenciadas pela textura propriamente dito, mas sim pelo NOME da textura, o que facilita tudo 10 mil vezes. Então ao invés de dar Resources.Load pra trocar a textura, simplesmente colocamos nguiSprite.spriteName = LanguageDictionary.stringList["chave"];, e ao receber o nome correto, o sprite do NGUI troca pra imagem certa.

(PS2: Se você usa NGUI, esse método tem um seríssimo problema. Se alguém quiser, posso explicar em outro post qual é o problema e como resolver esse problema de maneira fácil)

Usando NGUI no Like a Boss. Visualmente parece 10x + putaria que a imagem do Commander Flag... a diferença é que aqui tem uns 4 draw calls com muito mais elementos, enquanto la tinha uns 20... mas nem tudo ai é NGUI.
Esses métodos podem ser utilizados pra traduzir qualquer texto e imagem no seu jogo, sejam menus, legendas, falas, enfim, qualquer coisa. Pra ser bem sincero, eu suspeito que esses métodos, no entanto, tenham um problema meio chato. O primeiro deles é que procurar coisas em um dicionário... e pior ainda, procurar comparando string com string (quando você diz stringList["chave"], internamente o C# tem que procurar na lista toda do que é que você ta falando), é um processo que gera um certo overhead. Sinceramente eu evito ao máximo qualquer comparação de string, e dicionários as vezes não da pra evitar, mas quando possível, uso listas ou arrays. O segundo problema é que se você tem 100, 200, 500 strings... beleza (Level Up tem quase 500), mas conforme esse número vai crescendo, tanto a velocidade de procura quanto o uso de memória da sua stringList vai crescer... bom, digamos assim, se eu tivesse fazendo Mass Effect, não ia dar pra fazer desse jeito vagabundo =P.

Eu acredito que o jeito mais correto e profissional de fazer a coisa seja usando XML. Você cria um arquivo XML com todas as strings, e procura nesse arquivo o que você quer, e mostra o resultado da sua busca dentro do jogo. Esse método eu também vejo 2 problemas: o primeiro é que eu realmente não sei se fazer a busca num XML é la muito mais rápido/melhor que fazer a busca em um dicionário... afinal de contas é string com string do mesmo jeito... enfim, eu não manjo de XML (ou JSON que seja)... e o segundo e ainda maior problema... é que eu não sei fazer desse jeito =P, infelizmente não tive tempo pra ir procurar uma solução pra um problema que eu nunca tive, mas prometo que qualquer hora eu vou e posto um update aqui pra vocês, ou se alguma alma caridosa souber como ou um jeito ainda melhor de fazer essas traduções, deixa um comentário, por favor!

Pra quem ficou curioso, sim, essa é a arvore de skills do Like a Boss. Ainda estamos trabalhando em cima, na verdade essa imagem já é antiga, mas da pra dar uma ideia...
Por fim, resta o problema de traduzir sons... e bem, esse problema vai continuar restando =P. Sinceramente, se eu tivesse que fazer hoje um sistema de tradução de sons ia ser na base do Resources.Load e carregar o som certo na língua certa, mas não sei se essa é a melhor solução. Por outro lado eu suponho que o número de indies (ou índios) brasileiros que tem um jogo pra traduzir em várias línguas e vão traduzir o áudio também não seja o maior do mundo... imagino que o número de jogos indies com NARRAÇÃO de qualquer tipo já não seja muito grande graças ao preço infeliz de fazer uma narração boa pro jogo... (se alguém conhecer um estúdio bom e barato, favor mandar o contato pra gente! contact@firehorse.com.br (PS3: não estou falando que acho narração uma coisa ruim... Bastion só ta nos meus top 5 jogos por causa da narração, e Mass Effect, Dragon Age também tão nessa lista e com certeza a narração ajudou bastante... só digo que é caro a ponto de ser inviável produzir mesmo (pelo menos os orçamentos que já fizemos nos levam a pensar assim (pelo menos com nossa verba limitadíssima))))

Bom, acho que no mais é isso! Se ficar com alguma dúvida, tiver um método melhor ou simplesmente quiser saber mais sobre qualquer assunto aqui do blog, ou até sugerir algum assunto, deixa um comentário ou entra em contato direto com a gente!

Abraços,
Allan

sexta-feira, 20 de setembro de 2013

Sistema de Inventario + Overloadable Operators

E ae pessoal, tudo bem?

Já faz alguns dias... alguns vários dias pra ser bem sincero... que eu estou trabalhando no Sistema de Inventário do Like a Boss. Oficialmente essa é a primeira vez que eu faço um sistema de inventário, todos nossos outros jogos era meio que migué, a loja era o inventário e se o item tava comprado trocava de "Comprar" pra "Equipar" e é isso ai.

Sério... quando eu comecei esse sistema, eu pensei "bom, inventário... vai ser tranquilo... pega o item, joga numa lista de itens... quando o kra abrir o inventario preenche a interface com base nessa lista... e ja era, cabo!!!!1111"

Nunca...
Pra falar a verdade eu to impressionado como essa porra de sistema ta me dando trabalho. Mas a verdade é que, basicamente, ele realmente é só adicionar e tirar de uma lista, como q pode ser tão difícil assim? Bom, é ai que começa a putaria da programação. Como q eu posso adicionar e tirar items de uma lista, se eu nem sei o que é um item? Como vou subdividir meus items, que propriedades essas porra de item tem que ter? Bom, blz, tão vamo la, definir o que é um item!

Eu sei que Like a Boss tem genericamente falando 5 tipos de item: Equipamentos (Armaduras e Armas que podem receber upgrades), Gemas (para colocar nos equipamentos), Poções (para tomar (não me diga)), "Brincos" (na verdade qquer porcaria, são um tipo de equipamento mas sem modelo, sem slot pra gema, sem poder dar upgrade) e por fim... lixo, que é sempre bom pra encher os inventários alheios.

Depois de ownar horrores com The Unstoppable Force dando knockback em geral... chega às lojas... The STOPPABLE Force! Essa é a alma dos itens lixo... são lixo, mas são da hora =P
Cada um tem características bem diferentes um do outro... alguns tem modelo atrelado... outros pode dar upgrade... outros tem efeitos diferentes se usado de maneiras diferentes... enfim, acabei por criar uma classe Item e uma pra cada tipo de item com as características únicas de cada um, até ai, tranquilo.

O problema é quando você começa a perceber que isso é só o comecinhoooo de nada... Os itens atualmente (mas pode mudar) são por chefe, e não por player. Já que você pode jogar com vários chefes diferentes, cada um tem sua campanha, cada um tem seus items. Isso ainda está em discussão, mas no momento é assim. Então primeira coisa é fazer toda a lógica de toda a interface do inventário funcionar com base no chefe atual, e criar a lista de inventário por chefe. Só que ai, também tem que fazer a lista de itens equipados... só que ai, precisa pegar os stats dos items equipados e incrementar nos stats do player... só que ai, precisa definir todos os stats que existem no jogo... só que ai, precisa definir como eles vão funcionar internamente... só que ai, precisa implementar nos códigos antigos multiplicadores e a porra toda... só que ai, precisa criar um operador custom pra somar uma puta lista de stats com outra lista... só que ai, eu preciso salvar os itens que estão na bag... só que ai, preciso duplicar os items de um banco de dados para a bag... só que ai.... sério, eu to a uns 4-5 dias só no "só que ai..."

Mas eu só queria fazer um sisteminha de inventário...
Enfim, dizer "sistema de inventário", é ser muito bonzinho. Na verdade estou trabalhando no sistema de stats + inventario + upgrades + sockets + input + efetivamente dar efeito aos stats. Não é a toa que essa porcaria ta me tomando tanto tempo. Na verdade é tanto tempo que hoje eu tive que trabalhar em outra coisa (alguns bugfixes principalmente), pra depois voltar, porque eu to sentindo que até o sistema de inventario estar 100% pronto pra colocar no jogo e o player efetivamente ter items, ainda vai levar mais alguns dias... ah, e PS: não são dias 4-5 dias de 8 horas de trabalho... são 4-5 dias dormindo no escritório...

Assim que eu me sinto quando durmo no escritório sem chuveiro...
Claro, fiz outras coisas nesse período, algumas pendências ainda do jogo do Cartoon, um monte de contatos que eu precisava responder, coisas que precisava escrever, atualizar o blog que é minha promessa... haha mas enfim, ta sendo tenso.

Alias, pra esse não ser um post totalmente voltado pras minhas choradeiras do dia a dia, eu mencionei ai pra cima uma coisa que eu tenho certeza que muita gente não sabe que existe/não sabe como fazer/ta pouco se fudendo: operador customizado!

Qué isso Allan, to super interessado em saber como são esses tal de operadores!!11
O que que eu realmente quero dizer com isso? Bom... pra nós é obvio que quando eu escrevo 1 + 1, o que eu quero dizer é que é pra máquina somar 1 ao 1 inicial, pra me dar um outro resultado numérico. Outro exemplo que se torna óbvio de tanto que a gente usa é dizer que "string1" + "string2" = "string1string2", pq afinal de contas é obvio que eu to pedindo pra máquina concatenar as strings pra me formar uma 3a string (PS: evitem concatenar strings sempre que possível). Mas, por exemplo no meu caso, eu tenho uma classe chamada BossAttributes, que tem todos os atributos do chefe. O que acontece se eu disser BossAttributes1 + BossAttributes2????


Porra nenhumaaa!!! Aeeee!!!1111 Bom, pra ser justo, acontece, a máquina basicamente vai me dizer "porra, qq vc quer q eu faça com essa merda, sô adivinho por acaso???" porque o computador não sabe o que "+" quer dizer nesse sentido. O que o OPERADOR "+" quer dizer... mas eu, por sua vez, sei. Eu quero que ele pegue todos os atributos do chefe, e some com os pares do outro lado... então, pra exemplificar, digamos que eu tenho AttackPower, Health e Armor. Quando eu digo BossAttributes1 + BossAttributes2, eu quero que ele faça, na prática: BossAttributes1.AttackPower + BossAttributes2.AttackPower, BossAttributes1.Health + BossAttributes2.Health... e dai por diante... mas, como que eu ensino a máquina a aprender a fazer soma básica?

É tão simples que chega a ser escroto. Eu nem sei se tem muito o que explicar, quando vocês verem a sintaxe do negócio. Vou colocar uma imagem do código que fica mais fácil.

PS: Atualmente esses sao os atributos do Like a Boss.
Bom, como vocês podem ver, tudo que você precisa fazer é criar um método static (dentro da classe), que retorna o tipo da sua classe, com a palavra chave operator, e dizer que tipo de operador você ta dando overload. Nos parâmetros você passa (nesse caso) os dois valores que vão ser "somados", e ai você simplesmente escreve o código do que você quer que a máquina faça. A partir desse momento, eu posso dizer que BossAttributes1 + BossAttributes2 e a máquina efetivamente sabe o que eu quero dizer com isso, e que é pra somar do jeito certo. Existe uma lista de operadores que podem ser "sobrecarregados" (a tradução de overloaded pra esse caso não me agrada muito), e algumas notas a serem consideradas, aqui. Alias, outra dica é, tudo que você quiser saber de C#, se você souber o que procurar, existe na documentação da Microsoft... o que é algo mto legal da linguagem diga-se de passagem.

Eu nunca usei muito isso, mas eu sei que existem casos em que isso facilita d++++ a vida, esse é certamente um deles. Outros operadores podem abrir outras possibilidades, e se alguém que tiver lendo já usou pra alguma coisa diferente e saiba uma dica pra dar de algo que possa ser útil ou uma correção a algo que mencionei, por favor deixe um comentário!

Abraços,
Allan

quarta-feira, 18 de setembro de 2013

Players de Elite!

E ae pessoal,

Bom, antes de mais nada fiquei sabendo hoje que Like a Boss é um dos finalistas do SBGames 2013! Aeeee! =) Enviamos o jogo como "Em Produção" por falta de uma categoria "Alpha do Beta do Theta", não estávamos muito confiantes, a gente tinha trabalhado só 1 mês no projeto... e... lá estamos nós! Aeeeee! =)

Ano passado o evento foi show de bola, espero que esse ano seja ainda melhor.
Pra quem tiver interesse e ainda não tenha visto a lista completa de jogos finalistas, pode acessar esse link. Pelo que entendi desde o começo, ainda vai ter mais uma eliminatória antes do evento, mas não tenho certeza. De toda forma, é legal passar de qualquer fase de qualquer concurso, e esse ano a competição ta bem complicada, uma porrada de jogo bom... da até orgulho de ser brasileiro =P.

Só aproveitando esse momento pra fazer um comentário, eu acho realmente muito triste saber que enquanto ano passado, nessa época do ano, corríamos e nos preparávamos para SBGames, BIG e BGS, este ano só vai acontecer o SBGames... eu entendo que organizar um evento de grande porte não é nada fácil, mas a impressão que tenho é que o pessoal não sabe como é importante pros indios poder participar desses eventos... o BGS vai acontecer, mas sem Festival de Jogos... os caras tem uma baita estrutura, arrecadam uma puta grana de patrocinadores e expositores, e estão cortando as pequenas, porém importantes medidas de incentivo pros desenvolvedores nacionais... e o BIG, que talvez tenha sido meu evento preferido do ano passado por ter todo um lado business que foi ULTRA importante pra gente... não vai acontecer esse ano, uma grande pena... =(

Queria eu fazer uma piadinha first world problems... se nossa situação como desenvolvedor no Brasil não fosse tão precária...
Mas, enfim, não adianta chorar o leite derramado... hoje eu vim aqui pra fazer o que se deve fazer em um dev blog... falar sobre dev! Quem diria que esse dia ia chegar!

E como meu primeiro tópico oficialmente sobre dev, vou falar sobre uma coisa que eu não vejo a hora de implementar no Like a Boss: Players de Elite!

Existe player mais elite que o grande Leerooooooyyyy Jenkiiinnss???
Bom, como já mencionamos algumas vezes em outros posts (tipo esse e esse), em Like a Boss, você, o player, é na verdade o Boss que tem que arregaçar os players. Mostrar quem é que manda nessa bagaça! Os "players" em geral são bem noobs (eu quero dizer os "players" do Like a Boss, mas é válido pros players do mundo real também), mas, vira e mexe sempre aparece um cara acima da média. Um cara que manja dos paranaue de matar chefe, player, do lore, das mecanicas internas do jogo... sempre tem uns no life pra fazer uma puta engenharia reversa e se tornar o kra mais eficiente possível dentro do jogo. Posso dizer que foi uma época legal da minha vida, quando invés de inventar mecânicas internas eu tinha que descobrir elas... inventar da muito trabalho... =P

Mas, enfim, essa característica dos players não podia deixar de aparecer no Like a Boss! Os players comuns no jogo representam as classes comuns de RPGs, Arqueiros, Guerreiros, Magos, Sacerdotes, Paladinos, etc etc etc... e pra IAs eles são consideravelmente inteligentes do jeito que são. Sabem a hora certa de usar habilidades, de bater, de fugir, sabem se ajudar... na verdade desde o começo uma das maiores preocupações com esse projeto é os players serem tão fodásticos que ser o chefe vai ser mais frustrante que divertido.

"Puta que pariu, como que pode ser tão dificil sair de cima do fogo??" - Pergunta mais misteriosa do mundo dos MMORPGs
Mas, não satisfeitos com a dificuldade natural do jogo (que claro, pode ser nerfada (de novo)), nós vamos implementar os Players de Elite. Eles são players especiais em todos os sentidos. Mais poderosos, mais inteligentes, com habilidades extras, alguns possuem auras que dão bonus para os aliados próximos, e mais importante: nenhum é igual ao outro. Os players de elite serão facilmente identificáveis por seus nicks, sendo os únicos players no campo de batalha com o nome em cima da cabeça. A idéia é que o Boss, com tempo de jogo, identifique os Players de Elite como seus nemêsis, por exemplo, um dos Players de Elite chamado Schwarzenego (acidentalmente o mesmo nick que eu uso quando jogo) tem um perfil extremamente agressivo, causa muito dano, muito rápido, é bem resistente, aumenta o dano dos aliados próximos... no entanto, de tempos em tempos precisa ficar away por alguns segundos pra responder pra mãe (que já ta de saco cheio dele ficar jogando esses joguinhos) que horas que ele vai sair do computador.

Queremos que o Boss (o jogador de verdade) se acostume com os perfis de cada Player de Elite, e que torne eles os vilões de verdade do jogo, pra sentir aquela sensação de "MORRE FDP" que é tão boa. Mas, players tão importantes no mundo de Like a Boss não podem se diferenciar apenas no nome né? Precisam se diferenciar também no modelo, afinal de contas os kras farmam o dia inteiro, os kras manjam das putarias, os kras tem item TOP!

Archer de Elite Mid level. Esse arrombado vai dar raiva viu... ja vo avisando.
Estamos atualmente trabalhando nos modelos e texturas dos Players de Elite, mas sério, os Elite High level... parece um Boss, os caras são tenso d+.

Esse corno é tão rápido e tem tanta skill pra fugir que se não fosse o dano absurdo, era melhor deixar ele por ultimo.
Como todos os players regulares, os Players de Elite também tem uma progressão. A progressão de todos os players acontecerá de acordo com o level do Boss, em tese porque conforme você (boss) fica mais foda, só players mais experientes vão tendo coragem de te enfrentar.

Eu poderia dizer que o negócio é ignorar esse cara. Com tanta vida e skills de proteção, enfrentar ele é pedir pra morrer. Mas, os Warriors de Elite são a definição de "se correr o bixo pega, se ficar o bixo come".
Ainda tem uma porção de questões sobre o gameplay do Like a Boss que estão em discussão (naturalmente), o formato dos levels, das quests, de uma porrada de coisa. Mas a gente ta colocando muitas fichas na mecânica dos players elite. A gente acha que eles vão dar uma boa variedade de gameplay, aumentar bastante replay value, e com certeza ajudar você a se sentir épico, como todo Boss tem que ser.

Já vou avisando... se você só tiver habilidades mágicas, e tiver que enfrentar esse cara... pode "largar o teclado". Ele reflete tanta magia que você vai se sentir jogando Tenis.
Infelizmente, no entanto, nenhum dos colegas acima está implementado =( Nem o colega abaixo, diga-se de passagem. Estamos trabalhando em sistemas mais "invisiveis" ao jogador, no exato momento estou trabalhando em implementar o sistema de inventário, que ta tenso. Ainda tenho algumas prioridades antes de implementar eles dentro do jogo, mas sinceramente é o que eu mais quero fazer já faz um bom tempo.

Sério, os Healers comuns já são um pé no saco. Se eu conhecesse 1 healer no WoW igual a 1 dos healers comuns do Like a Boss, eu era um cara feliz. Imagina 1 healer foda, o dobro + apelão?
Enfim, com certeza nos próximos dias/semanas teremos mais novidades sobre o sistema dos players de elite, quem sabe uns vídeos Alpha Beta Theta de gameplay? Mas, por enquanto é isso =P. Tem alguma idéia que acha que ia ser foda? Alguma coisa envolvendo Players de Elite que a gente ainda não pensou? Deixa suas sugestões nos comentários!

Abraços!

segunda-feira, 16 de setembro de 2013

Unity C# - Delegates e Eventos

E ae pessoal, beleza?

Como havia dito ontem, vamos começar a efetivamente tentar fazer posts diários sobre o andamento dos nossos projetos, decisões que tomamos, problemas que encontramos, etc, mas eu tinha escrito esse post a tanto tempo que tava escrito "acho que até o final de maio vamos ter muita coisa pra postar aqui..." hauhauha to me sentindo praticamente jogando Sim City no Cheetah Speed, negócio ta tenso... mas, enfim, esse post é dedicado a programação novamente, sobre um tópico que aprendi recentemente e tem me ajudado muito na produção dos nossos jogos, algo que é EXTREMAMENTE ÚTIL, Delegates e Eventos!

Esse é um tutorial talvez um pouquinho mais avançado que o de Singletons, mas de verdade, é bem simples, vou tentar explicar de um jeito bem fácil de entender. Outra coisa que acho válido mencionar logo de cara é que eu sou noob de delegates e eventos e eu ainda sinto que não estou usando isso a todo o poder... por isso, fique a vontade nos comentários pra me chamar de retardado. (Também é C#, pra Unity)

-Delegates e Eventos

De acordo com o google images, pra manter o padrão...

Impressionantemente, uma imagem que realmente descreve o que é um delegate com eventos!
Tendo em mente que eu não sou nenhum mestre dos delegates, eu diria que Delegates e Eventos podem fazer juntos de maneira simplória: Em uma classe, você cria um delegate (praticamente como um método, você da um nome, um tipo de retorno e quantos parâmetros esse método recebe), e um evento que é do tipo do delegate (isso é, um evento que recebe os mesmos parâmetros e retorna a mesma coisa que o delegate criado). Agora, todas as classes do seu projeto podem se "inscrever" no seu evento, e serem avisados que aquele evento foi chamado pra fazerem seja lá o que eles quiserem fazer.

Ok, não foi a melhor explicação do mundo, mas calma, eu explico melhor mais pra baixo.

Bom, mesmo sendo noob dos delegates, eu já descobri alguns usos que são simplesmente fantásticos. Um exemplo que eu acho muito útil é para controlar Inputs (principalmente mobile, mas é útil de toda forma). Vamos supor você tem um jogo de matar monstrinho, e na tela existem 5 botões referentes a suas habilidades pra matar monstrinho. Muito provavelmente você tem uma classe que é responsável por controlar os inputs (vou chamar aqui de InputHandler), e nessa classe você diz que quando um dedo toca a tela, o jogo deve lançar um Raycast da câmera pra dentro do jogo, descobrir se acertou algum botão, e SE acertou, soltar a magia. Maravilha.

No entanto, sem delegates e eventos, a sua classe InputHandler está diretamente atrelada a sua classe SkillHandler, que gerencia o uso de todas as magias. Obrigatóriamente você precisa de uma referencia ao SkillHandler dentro do InputHandler, e quando um dedo bate em um botão, você chama algo tipo SkillHandler.UseSpell(2) onde 2 é o index do botão tocado.

Maravilha, funciona... mas e se agora você decidiu fazer uma tela de stats de jogo, então você quer marcar quantas vezes cada habilidade foi usada? E se agora você quiser que toda vez que o jogador use a magia X, uma luz mude de cor? E se agora você quer que comece a chover sempre que o cara use uma magia de água? Vai socar todas essas checagens no InputHandler? Vai deixar uma classe ser totalmente dependente da outra pra que tudo isso funcione direito?

Esse é certamente um dos inúmeros casos em que os delegates salvam o dia. O InputHandler deve ser responsável pelo Input e nada mais. As outras classes precisam simplesmente receber o input e tratar da maneira correta para saber o que fazer com aquele input. Sem delegates, seria necessário criar referência de todas as classes que possam precisar de input no inputhandler, para fazer chamadas diretas de métodos, ou pelo menos pra enviar mensagens para esses objetos. Mas com delegates... isso é tudo diferente, e na verdade, muito mais simples.

Bom, a primeira coisa a se fazer nesse caso é efetivamente criar um delegate na classe InputHandler, e atrelar um evento a este delegate. Isso é feito da seguinte forma:



Agora, para facilitar ainda mais as coisas, podemos considerar a classe InputHandler um singleton, afinal de contas nós queremos que ela centralize todos os inputs recebidos e apenas de as ordens para as outras classes, você jamais precisará de duas instancias dessa classe em uma cena. Para isso, como conversado neste post, vamos adicionar as seguintes linhas pra classe InputHandler:


E finalmente, para acabar a classe InputHandler, vamos adicionar uma chamada ao evento que foi criado anteriormente. Essa chamada deve acontecer no momento em que o botão da skill é pressionado, como por exemplo no código:


Agora, vamos trabalhar na classe SkillHandler. Ela deve efetivamente soltar a magia quando o botão for pressionado. O código aqui é bem simples, e a classe ficaria assim:


Mas o que estamos fazendo aqui? Bom, no OnEnable, isso é, quando essa instancia ficar ativa, nós estamos registrando essa instancia da classe no evento OnSpellUse, da classe InputHandler, e dizendo na hora do registro que o método a ser chamado é o método UseSpell(). Na prática, o que isso quer dizer é que sempre que o InputHandler chamar o evento onSpellUse(); como demonstrado um pouco acima, o método UseSpell() da classe SkillHandler será chamado automaticamente. Na prática, o InputHandler não sabe absolutamente nada sobre a classe SkillHandler, mas mesmo assim consegue chamar o método UseSpell() indiretamente.

Ainda na classe SkillHandler, é importante adicionar o seguinte código:


Dessa maneira, quando a classe SkillHandler for desativada por qualquer motivo que seja, ela se desvinculará do evento do InputHandler, liberando uma referência na memória, e assim o método UseSpell não será mais chamado pelo InputHandler quando o evento for chamado.

Seguindo a mesma lógica da classe SkillHandler, poderíamos criar uma classe chamada... sei la, WeatherHandler, que muda o clima de acordo com as habilidades usadas. O código dessa classe inicialmente seria bem semelhante ao código da classe SkillHandler:


Dentro do método ChangeWeather(), seria necessário verificar como efetuar a mudança do clima, pra que clima deveríamos mudar (chuva, sol, vento, etc), enfim, todas as checagens referentes a mudar o clima seriam feitas aqui. E, assim como UseSpell na classe SkillHandler, esse método será automaticamente chamado assim que o evento onSpellUse() for chamado no InputHandler.

É possível criar inúmeros registros em apenas um evento, e dessa forma fazer com que várias classes respondam.

Um projeto básico de exemplo está disponível aqui, com as classes mencionadas neste post. Qualquer dúvida ou sugestão, deixa um comentário! Se quiser me esclarecer sobre outros usos de delegates e eventos, eu fico muito agradecido!

Grande abraço,
Allan

Apresentando... Like a Boss!

E ai pessoal, tudo bem?

Bom, é fácil dizer que este até hoje não tem sido um blog de desenvolvimento. Infelizmente nós estamos tendo muito pouco tempo pra postar sobre o nosso trabalho por aqui, e isso acaba resultando em um blog rarissimamente atualizado, o que é muito triste.

"Tenho tanto trabalho pra fazer que nem consigo atualizar meu blog sobre o trabalho..."
Só não é mais triste que ver nossas outras mídias também tão pouco atualizadas, como Facebook e o Website, mas prometo que vamos trabalhar nisso a partir dessa semana, com um enfoque especial aqui no blog! Vamos tentar nosso máximo para fazer um post por dia contando nosso progresso diário em cima de nossos projetos, e todo final de semana vamos fazer um post com um recap e falando um pouco mais sobre o que planejamos fazer. Este por ser o primeiro de muitos, vai ser um post de introdução sobre as coisas das quais vamos falar, principalmente sobre nosso novo jogo.

Bom, antes de mais nada, relembrando, a algum tempinho atrás mencionei o jogo em que estamos trabalhando, Level Up: Heroes of Neverfail, para o Cartoon Network, ele está prestes a ser publicado para a América Latina e sendo traduzido para mais 5 línguas para ser publicado na Europa também. Estamos bem ansiosos pra saber como vai ser a recepção dos jogadores, e quando ele for publicado oficialmente, volto a comentar aqui!

Mas, existe um outro projeto no qual estamos bem empolgados em trabalhar que ainda nem mencionei aqui no blog (pelo menos essa versão), e que certamente vai ser o foco das próximas postagens... e o nome desse projeto é...

Qualquer semelhança com o logo de um jogo famoso é mera coincidência
Imagino que alguns de vocês que tiveram o saco de ver nossos posts mais antigos aqui no blog já estejam de certa forma familiarizados com a ideia deste jogo, que é muito simples: Você é o Boss. Você gosta de passar seus dias relaxando na sua sala maquiavélica, quando de repente 40 players sem ter mais o que fazer da vida saem matando todos seus amigos e estão loucos pra dançar em cima do seu corpo, enquanto roubam tudo que você juntou durante toda sua vida. Isso é, se você permitir.

A ideia do Like a Boss surgiu durante o Global Game Jam deste ano, quando fizemos uma versão para web/pc em 48 horas. Das 48 horas, passamos 9 horas apenas conversando e discutindo e pensando e elaborando e repensando...como mais detalhadamente descrito neste post, nossa ideia era sair de la com um jogo que a gente achasse legal e que pudesse vir a se tornar um jogo completo, e saímos de la com Like a Boss (que pode ser jogado neste link).

Simples, sem dúvida... mas ficamos muito orgulhosos, 48 horas mto bem gastas =)
No entanto, esta versão inicial era pra PC e apesar de na época estarmos apaixonados pela ideia do jogo, estávamos sem tempo de continuar a produção do mesmo. Estávamos trabalhando em cima do Knights Trial, em pé de fechar o contrato com o Cartoon Network, correndo atrás de 1000 coisas... infelizmente o projeto ia ter de esperar... até agora!

Voltamos a trabalhar no Like a Boss dia 1 de julho de 2013. Queríamos enviar uma versão jogável para o SBGames 2013, por isso voamos na produção. Começamos o projeto do 0, dessa vez pra mobile, então todos os modelos, scripts, tudo de tudo precisou ser refeito. Na verdade para conseguirmos otimizar o jogo para 40 inimigos simultaneamente, precisamos otimizar o jogo a um nível que nunca tínhamos otimizado antes. Mudamos completamente o estilo visual do jogo, mudamos o esquema de controle, mudamos... tudo =P menos a ideia central do jogo. E em 1 mês de produção paulera, nosso resultado foi esse:

Vídeo de gameplay enviado ao SBGames 2013. Impressionante como já mudou bastante desde então.

Na realidade nós ficamos muitíssimo satisfeitos com esse estágio alpha de desenvolvimento. Em apenas um mês conseguimos implementar 12 habilidades, 3 inimigos bem inteligentes, uma boa parte dos menus do jogo, 2 cenários, 1 chefe, 1 inimigo chefe... mas com certeza ainda faltava muito a ser desenvolvido. Na verdade, nós estimamos que este projeto levará em torno de 12 meses para ser completamente terminado, e ainda estamos no 3o mês de produção.

Warrior correndo. Ainda ta com o set inicial, noob.

Bom, como na versão inicial a ideia é que seus inimigos sejam os players, representados pelas classes tradicionais de players. Atualmente estão implementadas apenas 3 classes, Warrior, Archer e Priest, podendo ser Warrior Tank, Warrior DPS, Priest Holy, Priest Shadow e Archer DPS. Cada um deles possui 6 habilidades e fazem de tudo para se manterem vivos. Possuem um tempo de resposta, desviam de golpes, se curam, se ajudam. E claro, reclamam pra burro que os outros são noobs.

Os players vão ficando menos noobs com o tempo, graças ao farm desgraçado por item.
Diferentemente da versão original no entanto, estamos trabalhando em cima de vários sistemas de progressão. A progressão mais básica do jogo se da através do sistema de XP, bem tradicional. Ao matar players, você ganhar levels, com levels você fica mais forte. O jogo também contará com um sistema de itens mais complexo do que os outros jogos que já trabalhamos. Os itens terão qualidade (comum, raro, lendário, épico), e poderão ser de 6 tipos, Capacetes, Luvas, Botas, Torsos, Armas e Anéis, e podem receber upgrades e gemas que melhoram seus atributos.

No one knows what its like to be the bad man behind blue eyes...
Alem disso, outro sistema muito legal que pretendemos implementar em Like a Boss é o sistema de customização da sala de seu Boss. Como inicialmente você é apenas um NPC a ser morto para uma quest simples, sua sala é pequena e simples... mas conforme você vai provando sua força e derrotando mais e mais players, você conquista o direito não só de expandir sua sala mas também de posicionar armadilhas que podem ser combinadas com suas habilidades para efeitos devastadores nos jogadores.

A arena do Caveirão. Quantas armaduras não ficaram vermelhas nessa sala, quebradas pela arma do chefe...
Outra coisa que está sendo nova para nós e que pela primeira vez estamos trabalhando em um jogo com história! Não só é porradaria pra la e pra cá, mas os players e o próprio chefe contam a história do que está acontecendo no mundo do jogo e todas as suas ações não são apenas em vão. Atualmente, a primeira histórinha que o jogador tem contato é do chefe Skeleton King (o único implementado no momento), que esta tranquilo em sua sala da dungeon quando grupos e mais grupos de jogadores começam a aparecer e discutir uma certa quest que lhes foi dada pelo Coveiro, um NPC que vive do lado de fora de sua dungeon, e com o passar dos grupos Skeleton King percebe que o Coveiro NPC traidor é quem está oferendo uma recompensa por sua cabeça. Em outras palavras, é hora de sair da dungeon e mostrar pro Coveiro quem é o NPC mais foda. E assim, o jogador conhece o sistema de quests do jogo, tendo sua primeira missão de matar de uma vez por todas o coveiro, e aproveitar e dominar uma cidade pra expandir seu território.

O Coveiro... NPC que da quest pra matar NPC não é NPC de verdade... é PNC
Enfim, sinceramente essa é só a ponta do Iceberg, nós temos uma porrada de idéias legais pra implementar nesse jogo e vamos discutindo aqui no blog conforme formos implementando, mas desde já gostaria de pedir o feedback de vocês, sobre tudo, sobre qualquer coisa! Vamos fazer algumas sessões de teste nas próximas semanas, e pouco tempo depois vamos precisar de alpha testers que estejam interessados em nos ajudar, por isso se você quer saber mais sobre o projeto, entra em contato com a gente, ou aqui pelo blog ou pelo e-mail contact@firehorse.com.br.

Nos próximos dias vou fazendo updates pequenos aqui no blog sobre ferramentas, modelos, texturas que estão sendo implementados, e no próximo final de semana volto a fazer um post um pouco mais completo. Se tiverem dúvidas sobre qualquer aspecto de qualquer coisa, não só do Like a Boss, da um toque pra gente e podemos esclarecer as coisas aqui pelo blog.

Valeu pessoal, brigado pela atenção prolongada! =P
Abraços,
Allan