Notícias / ONI Games

Como criamos um site de jogos com 300 páginas em 16 idiomas usando um só script Python

Sem CMS e sem framework: um arquivo Python escreve cada página do onirealms.com em 16 idiomas, e um pequeno Cloudflare Worker entrega tudo.

Fazemos jogos gratuitos para Android: dois RPGs idle, um quebra-cabeça de blocos e um tycoon de fábrica de robôs. Cada um precisava da sua própria página, e cada página tinha que existir em todos os idiomas em que os jogos são jogados. São 16 versões: inglês, alemão, espanhol (Espanha e América Latina), francês, croata, indonésio, italiano, japonês, coreano, português (Brasil e Portugal), russo, esloveno, turco e chinês tradicional.

Um CMS parecia pesado demais para um site que muda quando um jogo muda. Então todo o onirealms.com é escrito por um único script Python como arquivos estáticos simples, com um pequeno Cloudflare Worker na frente.

Como é montado

O script, site.py, é um único arquivo de cerca de 3.200 linhas. Ele guarda um dicionário GAMES com uma entrada por jogo: nome do pacote, tema, arte principal, as faixas de arte entre as seções, gêneros, classificações etárias e se o jogo já foi lançado. Todo o resto vem daí.

Os textos ficam em dicionários Python comuns, separados por idioma, um módulo por área: a página inicial, cada jogo, as perguntas frequentes, títulos e descrições de SEO, guias e notícias. Uma página de jogo é uma função que recebe um jogo e um idioma e devolve HTML. Quatro jogos em 16 idiomas, mais página inicial, notícias, guias, um catálogo de ciborgues, a política de privacidade e o kit de imprensa, somam mais de 300 páginas. Um build completo leva cerca de 26 segundos.

A arte de loja do Block Brain em japonês, alemão e russo.
A arte de loja do Block Brain em japonês, alemão e russo.

No fim, três coisas importaram mais do que o próprio gerador.

1. O hreflang precisa estar completo, senão não serve para nada

Cada página aponta para todas as outras versões de idioma dela mesma, incluindo ela própria, mais um x-default. O sitemap repete os mesmos grupos. Se faltar um, os buscadores tratam as páginas como quase duplicatas sem relação. O script monta esses links a partir da mesma lista de idiomas que usa para escrever as páginas, então os dois não têm como sair de sincronia.

2. Redirecionamentos de idioma não podem prender os robôs de busca

O Worker manda quem chega a uma página em inglês para a mesma página no idioma do navegador. Isso é ótimo para os jogadores e péssimo para a busca se for feito de forma ingênua, porque o robô só veria o redirecionamento. Por isso, não há redirecionamento para bots, nem para quem vem de outra página do site (escolheu inglês de propósito), nem quando o endereço tem ?lang=, e nenhum cookie é usado. É um 302 com Vary: Accept-Language, nunca um 301.

3. Arquivos imutáveis precisam de nomes novos

Tudo em /assets/ é servido com Cache-Control: max-age=31536000, immutable. É a configuração certa, até você trocar uma imagem e ninguém ver a mudança por um ano. Por isso os scripts de arte gravam um nome de arquivo novo para cada versão em vez de sobrescrever o antigo.

A arte de loja dos quatro jogos: Block Brain em coreano, Idle AI Factory em turco, Idle Summoner e Idle Ronin em inglês.
A arte de loja dos quatro jogos: Block Brain em coreano, Idle AI Factory em turco, Idle Summoner e Idle Ronin em inglês.

Pequenas peças que valem a pena

  • QR codes em cada página de jogo, gerados no build. Eles apontam para um link curto /go/<game> no Worker, que redireciona para o Google Play com uma tag de origem, assim o Play Console mostra as instalações por fonte.
  • Analytics com consentimento. A tag começa com todo tipo de armazenamento negado (consent mode v2) e só é ativada depois que o visitante aceita no banner de cookies.
  • IndexNow depois de cada deploy, para o Bing e o Yandex verem as mudanças no mesmo dia.
  • Um feed RSS por idioma, para leitores de feed e agregadores pegarem as notícias.
  • Kits de imprensa em arquivos ZIP, montados por um script a partir da arte dos jogos.

O que faríamos diferente

Escrever a lista de idiomas e as tabelas de texto antes do HTML, não depois. Encaixar 16 idiomas num markup pensado para o inglês foi a parte mais lenta de todo o projeto: tamanho das linhas, fontes alternativas para japonês, coreano e chinês e uma fonte cirílica alternativa para o russo precisaram, cada uma, de uma rodada própria.

Os jogos são Idle Ronin: Cyber RPG, Idle Summoner: Pixel RPG, Block Brain e Idle AI Factory: Robot Tycoon, todos gratuitos no Google Play.

Todas as notícias

Todas as notícias