Assinatura de Apps do Google Play (Android App Bundle)

Antes de submeter um arquivo “.aab” ao “Google Play Console“, você precisa providenciar um arquivo de assinatura do seu app/jogo no formato “.pem
Essa assinatura é gerada a partir do arquivo “.keystore” do seu app.

Caso você ainda não tenha providenciado essa assinatura, será alertado com o seguinte erro ao final do upload:
"Para fazer o upload do Android App Bundle, você precisa estar inscrito na Assinatura de apps do Google Play."

  1. Para resolver esta questão, você deve clicar na seta que está logo acima do botão “Adicionar da Biblioteca”:
  1. Selecione a segunda opção: “Exportar e fazer upload de uma chave de repositório Java”:
  1. Cique no botão “FERRAMENTA PEPK”, que vai baixar o arquivo “pepk.jar”, mas não o abra. Esta ferramenta serve para gerar o arquivo “.pem” que você precisa enviar ao Google.
  1. Abra o Prompt de Comando (se estiver usando Windows) ou o Terminal (se estiver usando MacOS) e cole o seguinte comando substituindo os campos que estão em negrito:

java -jar “ENDEREÇO_DO_PEPK” –keystore= “ENDEREÇO_DO_KEYSTORE” –alias=”ALIAS_DO_KEYSTORE” –output=”ENDEREÇO_ONDE_QUER_SALVAR/private_key.pem” –encryptionkey=CHAVE_DE_ENCRIPTAÇÃO_FORNECIDA_PELO_GOOGLE

Como neste exemplo:

java -jar “C:/Users/marcelo/Desktop/pepk.jar” –keystore= “C:/Users/marcelo/Desktop/app.keystore” –alias=”marcelo” –output=”C:/Users/marcelo/Desktop/private_key.pem” –encryptionkey=df715022017b00c6471f8ba81705f4ba4fe93fc8cef27558a3eb956cd48b9de6aeb10fe8f7c7c9b13046a104a3bbe4ac5a092761fb833b695a11e6c09ffe3059d2a529a2

Explicação do exemplo:
Os 2 primeiros endereços utilizados no comando são a localização do arquivo “pepk.jar” e do arquivo “.keystore” do meu app.
O campo “alias” deve ser preenchido com o nome de usuário da “keystore” que você utiliza para compilar o seu app. (caso tenha esquecido seu “alias” e estiver usando o Unity, você pode encontrá-lo na janela “Player Settings” na aba “Publishing Settings“).
No campo “output“, você deve preencher o endereço do local onde desejará salvar o arquivo “.pem” gerado. Não se esqueça de colocar o nome do arquivo no final do endereço (como no exemplo: “private_key.pem“)
O campo “encryptionkey” não precisa ser preenchido entre aspas, ele é um código fornecido pelo Google na mesma tela em que você baixou a “Ferramenta PEPK”, na parte que descreve o comando.

  1. Pressione “Enter”
  2. Digite a senha da sua “keystore” e pressione “Enter
  3. Digite a senha do seu “alias” e pressione “Enter
  4. Um arquivo “.dem” será salvo naquele endereço que você especificou no comando. Agora, volte à página do “Google Play Console“, clique no botão “Chave Privada de Assinatura do App”:
  1. Selecione seu arquivo “.dem”
  2. Clique no botão “Concluir” e PRONTO!

ACABOU! Espero ter ajudado!

Como criar Android App Bundle no Unity

Hoje, o Google Play pede que os desenvolvedores criem os “Android App Bundles” para que os usuários possam baixar versões mais leves dos aplicativos disponíveis na loja.

O que é um Android App Bundle (AAB) e por quê ele foi criado?

Antigamente, para lançar um jogo na plataforma Android, bastava você gerar um arquivo “.apk” do seu jogo e disponibilizar aos usuários.

Para que um jogo rodasse em todos os smartphones do mercado, seu arquivo “.apk” tinha que suportar os 3 tipos de arquitetura de processador, que são: o ARMv7, o ARM64 e o x86.

O problema é que esse excesso de informações de arquitetura tornava os arquivos “.apk” grandes. Isso não só deixava os downloads mais lentos como usava mais dados de rede móvel (como 3G e 4G), afastando alguns usuários.

Então, para reduzir o tamanho do arquivo “.apk“, o Google passou a exigir que os desenvolvedores disponibilizem um arquivo “.apk” específico para cada arquitetura de processador, permitindo ao usuário baixar apenas o arquivo “.apk” compatível com o seu smartphone e sem o excesso de informações referentes às outras arquiteturas.

Para simplificar o trabalho do desenvolvedor, que tinha que enviar diversos arquivos “.apk” individualmente, o Google criou o Android App Bundle, que é um pacote com todos esses arquivos “.apk” dentro. Esse pacote é um arquivo de extensão “.aab” que pode ser criado no Unity.

Como criar um AAB e enviar ao Google Play?

Basta abrir a janela “Build & Run” do Unity, selecionar a opção “Build App Bundle (Google Play)“, clicar em “Build” e selecionar o local onde você deseja salvar o arquivo .aab.

Para enviar este arquivo ao Google Play, basta enviá-lo igual um arquivo .apk normal, na página “Versões de Apps”, da aba “Gerenciamento de Versões” do Developer Console.

Square Fists – New game on Early Access (Beta)

club01So… here’s the game I’ve been making ALONE since August 2018.
I won’t get into details now because I’ve been TOO busy working on this game, I’m making literally everything on my own (coding, 3D art, animations, UI, etc).
Here’s the link if you want to check it out:
https://play.google.com/store/apps/details?id=com.MarceloBarce.SquareFists

 

Inteligência Artificial Explicada – Westy West

Este é o primeiro de uma série de artigos teóricos sobre o desenvolvimento do jogo Westy West.
Compartilho aqui uma ideia geral de como funciona a Inteligência Artificial dos personagens do jogo.
Vou separar este artigo em 6 partes: Inimigos, Civis Inocentes, Policiais, Bandidos Procurados, Personagens Decorativos, Animais Defensivos e Animais Inofensivos.

1.0 Inimigos – Descrição geral

Os inimigos do Westy West são identificado pelas roupas pretas.
A aparência, a quantidade de vida, o armamento e o meio de locomoção do inimigo é sorteada no início de cada fase do jogo.
Eles são capazes de vagar pelo cenário, desviar de objetos que bloqueiam o caminho, perseguir o jogador e atacá-lo com armas brancas e de fogo com alcances e poder variados.

1.1 Inimigos – Estados de Humor

Os inimigos agem de acordo com 2 estados de “humor”: tranquilo e irritado
O estado “tranquilo” é o estado inicial de todo inimigo e ocorre enquanto este não avistou o jogador. Já o estado “irritado” ocorre após o inimigo avistar o jogador e é caracterizado por um som de surpresa e um balão de emoji sobre a cabeça do inimigo.

bandido-alerta
Inimigo avistando o jogador

1.2 Inimigos – Movimentação

Os inimigos se movimentam de maneira intervalada. O tempo deste intervalo depende de uma variável aleatória cujos valores mínimos e máximos dependem da fase em que o jogador se encontra. Quanto mais avançado o jogador estiver, menor será o intervalo de movimentos dos inimigos, tornando-os assim cada vez mais rápidos, porém, dentro de um limite aceitável que não estrague a experiência de jogo.

O estado de “humor” do inimigo também influencia na maneira como este se movimenta.
Durante o estado “tranquilo”, o personagem caminha pelo cenário em direções aleatórias, podendo inclusive ficar parado no lugar ou andar em círculos.
Já no estado “irritado”, o inimigo caminha constantemente em direção ao jogador com o objetivo de atacá-lo.

1.3 Inimigos – Ataque

O ataque dos inimigos é simples, ele ataca o jogador sempre que este estiver no alcance de sua arma, que pode ser 3 (pistola), 2 (espingarda) ou 1 (arma branca).

bandido-melee
Bandido tentando atacar o jogador com uma marreta

A frequência dos ataques (“fire rate”) depende do mesmo intervalo usado na movimentação, para que o inimigo nunca se mova e ataque ao mesmo tempo, visto que isso seria injusto com o jogador, que só pode fazer 1 ação de cada vez (mover-se ou atirar), além de ficar visualmente confuso num jogo com movimentação em grade, como o Westy West. (fizemos o teste)

 

1.4 Inimigos – Estupidez

O humor é uma das peças-chave do Westy West, e é caracterizado inclusive pela estupidez dos inimigos. Se por um lado, é necessário impôr dificuldade ao jogador, por outro lado, a estupidez dos inimigos cria cenas engraçadas, como inimigos se acertando acidentalmente ou destruindo objetos do cenário que estiverem entre ele e o jogador.

galinha
Galinha entrando na frente do tiro e morrendo

Isso funciona de maneira muito simples: o inimigo atira SEMPRE que o jogador estiver dentro do alcance de sua arma, não se importando em avaliar se há um obstáculo ou personagem no meio do caminho. Sendo assim, antes de atingir o jogador, o inimigo pode destruir objetos acidentalmente, ou ferir comparsas e cidadãos inocentes.

Os únicos inimigos incapazes de cometer estes erros são aqueles que utilizam armas brancas, pois estes precisam obrigatoriamente estar encostados no jogador para poder atacar, visto que suas armas possuem apenas 1 de alcance.

Isso cria situações inusitadas e engraçadas e é totalmente intencional.

2.0 Civis Inocentes

Os civis são os NPCs (personagens não-jogáveis) que apenas vagam pelas cidades do jogo. Eles usam roupas coloridas e ignoram a presença do jogador no cenário, a não ser que este ataque alguém.

2.1 Civis Inocentes – Movimentação

A movimentação dos civis inocentes é idêntica àquela dos inimigos. (item 1.2 do artigo)

2.2 Civis Inocentes – Pânico

Os civis podem entrar em pânico ao ouvir um disparo. Neste caso, eles levantam os braços e correm pelo cenário.

civis-panico
Civis levantando os braços em pânico

2.3 Civis Inocentes – Reação Violenta

Alguns civis possuem armas e começam a perseguir o jogador igual caso este os ataque. No momento em que sofrem um ataque do jogador, eles assumem o mesmo comportamento de um inimigo irritado (como descrito nos itens 1.1, 1.2 e 1.3 do artigo).

3.0 Policiais

Os policiais aparecem no jogo caso o jogador violente animais ou civis inocentes. Sendo assim, eles tem a finalidade de reprimir um eventual comportamento anti-ético por parte do jogador, visto que o jogo não visa estimular a violência gratuita.
Eles se comportam como inimigos (conforme o capítulo 1 do artigo).

policiais-ataque
Policiais atacando o jogador

4.0 Bandidos Procurados

Os bandidos procurados são aqueles que estão nos cartazes de “Procurado” que aparecem ao clicar no botão do canto superior esquerdo da tela, ou ao interagir com o cartaz que está presente nos Checkpoints do jogo.

Estes bandidos possuem aparência de civis inocentes, usando as roupas que constam nos cartazes de procurado, e dessa maneira podem ser descobertos pelo jogador.

procurado
Bandido procurado sendo descoberto e reagindo

Bandidos procurados caminham pelo mapa como um inimigo tranquilo (conforme o item 1.2 deste artigo) e não atacam o jogador caso não sejam atacados por ele.
No caso de o jogador atacá-los, os bandidos procurados sacam uma arma e começam a disparar contra o jogador (conforme o item 1.3 deste artigo).

5.0 Personagens Decorativos

Os personagens decorativos são os Pianistas, as Dançarinas e a Banda Mexicana.
Os pianistas não fazem nada além de tocar o piano.
As dançarinas dançam enquanto o pianista estiver tocando, e param caso este morra.

dancarinas
Dançarinas parando de dançar após morte do pianista

A Banda Mexicana passa o tempo todo tocando e olhando na direção do jogador. Caso um músico da banda seja morto, os outros continuam tocando seus instrumentos como se nada tivesse acontecido, e a música segue com a ausência (sonora) do instrumento que foi destruído.

bandafinal
Banda tocando com 1 integrante a menos e virando para o jogador

6.0 Animais Defensivos

Os animais que se enquadram nesta categoria são as cobras e cavalos, que ficam parados em pontos específicos do mapa e atacam indiscriminadamente qualquer personagem que passe muito tempo parado próximo a eles, seja o personagem controlado pelo personagem ou não.

inimigo-coice
Personagem tomando um coice fatal

Chamo estes animais de “defensivos” pois, mesmo no mundo real, estes animais se atacam apenas para se defender em situações onde se sentem ameaçados. É errado dizer “ataque de cavalo” ou “ataque de cobra”, e é por isso que incidentes com animais peçonhentos são chamados de “acidentes ofídicos” e não “ataques ofídicos”.

Estes ataques matam qualquer personagem instantaneamente.

7.0 Animais Inofensivos

Os animais inofensivos são as galinhas e os coiotes, ambos só caminham pelo cenário, da mesma maneira que um inimigo tranquilo (explicado nos ítens 1.1 e 1.2 do artigo) fazendo barulho e cagando pelo cenário.

Conclusão

O Westy West é um jogo mais complexo do que parece, e a Inteligência Artificial é apenas 1 dos diversos aspectos do jogo que levaram vários dias para serem refinados.
Me orgulho de ter chegado a este nível de trabalho tendo jamais feito um curso de programação, e fico feliz em compartilhar este conhecimento com novos programadores (e experientes também).
Espero, no futuro, escrever outros artigos sobre este jogo.

Westy West – Best Games of 2017

So this is how we end 2017… having developed one of the Best Android Games of the Year, according to Google Play.

This is the top of the cake for us, after an unexpectedly successful year, with Westy West featured on both the AppStore and Google Play with great user scores and reviews. We couldn’t imagine all this in the recent past, what a great year!

Westy West – 6 months later

So… besides not posting it here, Westy West was published on March, and now 6 months later, I feel like I should talk about it.

The whole project was a challenging but joyful experience, it was my first tile-based game ever and all the mechanics were completely new to me.

We also tried to make a very user-friendly monetization, with super cheap in-app purchases and non-annoying advertising.

The Wild West theme is something I always appreciated, so it was really fun to work on that, using our past references from movies and videogames.

The game got featured on both Google Play and the AppStore, which means a new achievement for us, since we never got featured on the AppStore before.

Now we’re excited working on a new title for the Westy West series.

New game on Open Beta

Gráfico de recursos.png
Our new game Westy West is available as Open Beta on Google Play.
This project was influenced by:
Looty Dungeon, Crossy Road, Westerado, Red Dead Redemption, Steppy Pants

We’re receiving great feedbacks and will release it soon for both Android and iOS, check it out.

EDIT: game released on both stores now!

Google Play: https://play.google.com/store/apps/details?id=com.CountrysideGames.WestyWest

 

AppStore: https://itunes.apple.com/us/app/westy-west/id1176352069?mt=8

Jogo multi-idiomas

Vamos precisar de:
– um Dictionary publico estático que armazena todas as palavras do jogo
– uma Função pública estática que define o idioma do jogo
– uma Função pública estática que puxa as palavras deste Dictionary quando você pedir elas

Para começar… crie uma classe C# estática pública chamada LanguageDictonary:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public static class LanguageDictionary {

//As palavras serão armazenadas neste Dictionary
public static Dictionary<string, string> stringList = new Dictionary<string, string>();

//Este é o idioma padrão do jogo (português)
public static SystemLanguage defaultLanguage = SystemLanguage.Portuguese;

//Lista de idiomas suportados
public static List<SystemLanguage> supportedLanguages = new List<SystemLanguage>();

//esta classe define o idioma e adiciona suas palavras no Dictionary
public static void SetLanguage (SystemLanguage language) {

//define os idiomas suportados
supportedLanguages.Add (SystemLanguage.English);
supportedLanguages.Add (SystemLanguage.Portuguese);

if (!supportedLanguages.Contains (language))
language = defaultLanguage;

//Aqui ficam as palavras em português
else if (language == SystemLanguage.Portuguese) {
stringList.Add ("Sim", "Sim");
stringList.Add ("Não", "Não");
}
//Aqui ficam as palavras em inglês
if (language == SystemLanguage.English) {
stringList.Add ("Sim", "Yes");
stringList.Add ("Não", "No");
}
}

//esta função puxa palavras traduzidas do dicionário
public static string GetTranslation (string stringToTranslate) {
if (stringList.ContainsKey (stringToTranslate))
return stringList [stringToTranslate];
else
return stringToTranslate;
}
}

A primeira função, SetLanguage (), deve ser chamada no início do jogo, definindo o idioma do usuário. Por exemplo:

//Supondo que você puxar o idioma do sistema
SetLanguage (Application.systemLanguage);

//Supondo que você queira definir manualmente o idioma
SetLanguage (SystemLanguage.English);

A segunda função, GetTranslation (), deve ser chamada sempre que você precisar de uma palavra traduzida. Por exemplo:

//Para mostrar a tradução de uma palavra no Log:
Debug.Log (GetTranslation ("Sim"));

//Supondo que você queira colocar uma palavra traduzida num componente de Texto
GetComponent().text = GetTranslation ("Sim");

É isso aí! Se tiver dúvidas, é só postar um comentário abaixo.

Multi-language game (Unity)

We’ll need:
– a public static Dictionary that stores all of the game’s words
– a public static Function that sets the game language
– a public static Function that gets words from the Dictionary when you need them

So first… create a C# public static class named LanguageDictonary:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public static class LanguageDictionary {

//The words will be stored in this Dictionary
public static Dictionary<string, string> stringList = new Dictionary<string, string>();

//This is the default game language (english)
public static SystemLanguage defaultLanguage = SystemLanguage.English;

//This list stores the supported languages
public static List<SystemLanguage> supportedLanguages = new List<SystemLanguage>();

//this class sets the language and add its words to the Dictionary
public static void SetLanguage (SystemLanguage language) {

//check if the language is in the supported languages list
supportedLanguages.Add (SystemLanguage.English);
supportedLanguages.Add (SystemLanguage.Spanish);

if (!supportedLanguages.Contains (language))
language = defaultLanguage;

//Here you add the english translations
if (language == SystemLanguage.English) {
stringList.Add ("Yes", "Yes");
stringList.Add ("No", "No");
}
//here you add the spanish translations
else if (language == SystemLanguage.Spanish) {
stringList.Add ("Yes", "Yes");
stringList.Add ("No", "No");
}
}

//this function gets words from the dictionary
public static string GetTranslation (string stringToTranslate) {
if (stringList.ContainsKey (stringToTranslate))
return stringList [stringToTranslate];
else
return stringToTranslate;
}
}

The first function, SetLanguage (), MUST be called at the beginning of the game, to set the language. Example:

//Supposing you want to get the user's system language
SetLanguage (Application.systemLanguage);

//Supposing you want to set the language manually
SetLanguage (SystemLanguage.English);

The second function, GetTranslation (), must be called whenever you need a translated word. Example:

//Supposing you want to put translated text in a Text component
GetComponent<Text>().text = GetTranslation ("Yes");

That’s it! If you have any questions, leave a comment below.

Retro Runners X2 is out!

rr_cover_everyplay

Countryside Games’ new Retro Runners is available on iPhone and Android.

The game was published as an update of the first Retro Runners so the links are the same:

Google Play:
https://play.google.com/store/apps/details?id=com.CountrysideGames.RetroRunners

App Store:
https://itunes.apple.com/us/app/retro-runners-the-endless-run/id693042806