DEV Community

Cover image for How we built a 300-page game website in 16 languages with one Python script
ONI Games
ONI Games

Posted on Originally published at onirealms.com

How we built a 300-page game website in 16 languages with one Python script

We make free games for Android: two idle RPGs, a block puzzle and a robot factory tycoon. Every one of them needed its own page, and every page had to exist in each language the games are played in. That is 16 locales: English, German, Spanish (Spain and Latin America), French, Croatian, Indonesian, Italian, Japanese, Korean, Portuguese (Brazil and Portugal), Russian, Slovenian, Turkish and Traditional Chinese.

A CMS felt like too much machinery for a site that changes when a game changes. So the whole of onirealms.com is written by one Python script as plain static files, and a small Cloudflare Worker sits in front of them.

The shape of it

The script, site.py, is a single file of about 3,200 lines. It holds a GAMES dictionary with one entry per game: package name, theme, key art, the art bands between sections, genres, age ratings and whether the game is live yet. Everything else is derived from that.

The texts live in plain Python dictionaries keyed by locale, one module per area: the home page, each game, the FAQs, SEO titles and descriptions, guides and news. A game page is a function that takes a game and a locale and returns HTML. Four games in 16 languages, plus the home page, news, guides, a cyborg roster, the privacy policy and the press kit, add up to more than 300 pages. A full build takes about 26 seconds.

Block Brain's store art in Japanese, German and Russian
Block Brain's store art in Japanese, German and Russian.

Three things turned out to matter more than the generator itself.

1. hreflang has to be complete, or it does nothing

Every page links to every other language version of itself, including itself, plus an x-default. The sitemap repeats the same groups. Miss one and search engines treat the pages as unrelated near-duplicates. The script builds these links from the same locale list it uses to write the pages, so the two cannot drift apart.

2. Language redirects must not trap crawlers

The Worker sends a visitor who lands on an English page to the same page in their browser language. That is good for players and terrible for search if you do it naively, because a crawler would only ever see the redirect. So the redirect is skipped for bots, skipped when the visitor came from another page of the site (they picked English on purpose), skipped when the address carries ?lang=, and it sets no cookie. It is a 302 with Vary: Accept-Language, never a 301.

3. Immutable assets need new file names

Everything under /assets/ is served with Cache-Control: max-age=31536000, immutable. That is the right setting until you change a picture and nobody sees it for a year. The art scripts write a new file name for every new version instead of overwriting the old one.

Store art for all four games
Store art for all four games: Block Brain in Korean, Idle AI Factory in Turkish, Idle Summoner and Idle Ronin in English.

Small pieces that earn their keep

  • QR codes on every game page, generated during the build. They point at a short /go/<game> link on the Worker, which forwards to Google Play with a referrer tag, so the Play Console shows installs per source.
  • Consent-aware analytics. The tag starts with every kind of storage denied (consent mode v2) and only switches on after the visitor accepts in the cookie banner.
  • IndexNow after each deploy, so Bing and Yandex see changes the same day.
  • An RSS feed per language, so feed readers and aggregators pick up the news.
  • Press kits as ZIP files, packed by a script from the game art.

What we would do differently

Write the locale list and the text tables before the HTML, not after. Retrofitting 16 languages into markup that assumed English was the slowest part of the whole project: line lengths, font fallbacks for Japanese, Korean and Chinese, and a Cyrillic fallback for Russian each needed their own pass.

The games are Idle Ronin: Cyber RPG, Idle Summoner: Pixel RPG, Block Brain and Idle AI Factory: Robot Tycoon, all free on Google Play.


Originally published on onirealms.com. ONI Games is an independent studio from Slovenia making games for Android.

Top comments (0)