
Notícias / ONI Games
Como criámos um site de jogos com 300 páginas em 16 idiomas com um só script Python
Sem CMS e sem framework: um ficheiro Python escreve cada página do onirealms.com em 16 idiomas e um pequeno Cloudflare Worker serve-as.
Fazemos jogos gratuitos para Android: dois RPG idle, um puzzle 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 de 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. Por isso, todo o onirealms.com é escrito por um único script Python como ficheiros estáticos simples, com um pequeno Cloudflare Worker à frente.
Como está montado
O script, site.py, é um único ficheiro com cerca de 3200 linhas. Contém um dicionário GAMES com uma entrada por jogo: nome do pacote, tema, arte principal, as faixas de arte entre secções, géneros, classificações etárias e se o jogo já foi lançado. Tudo o resto deriva daí.
Os textos estão em dicionários Python normais, 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 a 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. Uma compilação completa demora cerca de 26 segundos.

No final, três coisas importaram mais do que o próprio gerador.
1. O hreflang tem de estar completo, senão não serve para nada
Cada página liga a todas as outras versões de idioma de si mesma, incluindo a própria, mais um x-default. O sitemap repete os mesmos grupos. Se faltar um, os motores de busca tratam as páginas como quase duplicados sem relação. O script constrói estas ligações a partir da mesma lista de idiomas que usa para escrever as páginas, por isso as duas não podem dessincronizar-se.
2. Os redirecionamentos de idioma não podem prender os rastreadores
O Worker envia quem chega a uma página em inglês para a mesma página no idioma do navegador. Isto é ótimo para os jogadores e péssimo para a pesquisa se for feito de forma ingénua, porque um rastreador 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 não se usa nenhum cookie. É um 302 com Vary: Accept-Language, nunca um 301.
3. Os recursos imutáveis precisam de nomes novos
Tudo em /assets/ é servido com Cache-Control: max-age=31536000, immutable. É a configuração certa, até alguém trocar uma imagem e ninguém a ver durante um ano. Por isso, os scripts de arte gravam um nome de ficheiro novo para cada versão em vez de substituírem o antigo.

Pequenas peças que compensam
- Códigos QR em cada página de jogo, gerados durante a compilação. Apontam para uma ligação curta
/go/<game>no Worker, que reencaminha para o Google Play com uma etiqueta de origem, e assim a Play Console mostra as instalações por fonte. - Estatísticas com consentimento. A etiqueta começa com todos os tipos de armazenamento recusados (consent mode v2) e só é ativada depois de o visitante aceitar na faixa de cookies.
- IndexNow após cada publicação, para o Bing e o Yandex verem as alterações no mesmo dia.
- Um feed RSS por idioma, para os leitores de feeds e os agregadores apanharem as notícias.
- Kits de imprensa em ficheiros ZIP, preparados por um script a partir da arte dos jogos.
O que faríamos de outra forma
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: comprimento das linhas, tipos de letra alternativos para japonês, coreano e chinês e um tipo de letra cirílico alternativo para o russo precisaram, cada um, de uma passagem 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.







