News / ONI Games

300 Seiten in 16 Sprachen: unsere Spiele-Website aus einem Python-Skript

Kein CMS, kein Framework: Eine Python-Datei schreibt jede Seite von onirealms.com in 16 Sprachen, ein kleiner Cloudflare Worker liefert sie aus.

Wir machen kostenlose Spiele für Android: zwei Idle-RPGs, ein Block-Puzzle und einen Roboterfabrik-Tycoon. Jedes davon brauchte eine eigene Seite, und jede Seite musste in allen Sprachen existieren, in denen die Spiele gespielt werden. Das sind 16 Sprachversionen: Englisch, Deutsch, Spanisch (Spanien und Lateinamerika), Französisch, Kroatisch, Indonesisch, Italienisch, Japanisch, Koreanisch, Portugiesisch (Brasilien und Portugal), Russisch, Slowenisch, Türkisch und traditionelles Chinesisch.

Ein CMS wäre zu viel Maschinerie für eine Website, die sich ändert, wenn sich ein Spiel ändert. Deshalb schreibt ein einziges Python-Skript ganz onirealms.com als einfache statische Dateien, und ein kleiner Cloudflare Worker steht davor.

So ist es aufgebaut

Das Skript site.py ist eine einzige Datei mit rund 3.200 Zeilen. Es enthält ein GAMES-Dictionary mit einem Eintrag pro Spiel: Paketname, Theme, Key Art, die Bildbänder zwischen den Abschnitten, Genres, Altersfreigaben und ob das Spiel schon live ist. Alles andere wird daraus abgeleitet.

Die Texte liegen in einfachen Python-Dictionaries, nach Sprache sortiert, ein Modul pro Bereich: Startseite, jedes Spiel, FAQs, SEO-Titel und -Beschreibungen, Guides und News. Eine Spielseite ist eine Funktion, die ein Spiel und eine Sprache bekommt und HTML zurückgibt. Vier Spiele in 16 Sprachen, dazu Startseite, News, Guides, eine Cyborg-Übersicht, die Datenschutzerklärung und das Pressekit ergeben über 300 Seiten. Ein kompletter Build dauert etwa 26 Sekunden.

Die Store-Grafiken von Block Brain auf Japanisch, Deutsch und Russisch.
Die Store-Grafiken von Block Brain auf Japanisch, Deutsch und Russisch.

Drei Dinge waren am Ende wichtiger als der Generator selbst.

1. hreflang muss vollständig sein, sonst bringt es nichts

Jede Seite verlinkt auf jede andere Sprachversion von sich selbst, auch auf sich selbst, dazu ein x-default. Die Sitemap wiederholt dieselben Gruppen. Fehlt ein Eintrag, behandeln Suchmaschinen die Seiten als voneinander unabhängige Beinahe-Duplikate. Das Skript baut diese Links aus derselben Sprachliste, mit der es die Seiten schreibt, deshalb können die beiden nicht auseinanderlaufen.

2. Sprach-Weiterleitungen dürfen Crawler nicht einsperren

Der Worker schickt Besucher, die auf einer englischen Seite landen, zur selben Seite in ihrer Browsersprache. Für Spieler ist das gut, für Suchmaschinen fatal, wenn man es naiv umsetzt: Ein Crawler würde immer nur die Weiterleitung sehen. Deshalb gibt es keine Weiterleitung für Bots, keine, wenn der Besucher von einer anderen Seite der Website kommt (dann hat er Englisch bewusst gewählt), keine, wenn die Adresse ?lang= enthält, und es wird kein Cookie gesetzt. Es ist ein 302 mit Vary: Accept-Language, nie ein 301.

3. Unveränderliche Assets brauchen neue Dateinamen

Alles unter /assets/ wird mit Cache-Control: max-age=31536000, immutable ausgeliefert. Das ist richtig, bis man ein Bild ändert und es ein Jahr lang niemand sieht. Die Grafik-Skripte schreiben deshalb für jede neue Version einen neuen Dateinamen, statt die alte Datei zu überschreiben.

Store-Grafiken aller vier Spiele: Block Brain auf Koreanisch, Idle AI Factory auf Türkisch, Idle Summoner und Idle Ronin auf Englisch.
Store-Grafiken aller vier Spiele: Block Brain auf Koreanisch, Idle AI Factory auf Türkisch, Idle Summoner und Idle Ronin auf Englisch.

Kleine Teile, die sich lohnen

  • QR-Codes auf jeder Spielseite, erzeugt beim Build. Sie zeigen auf einen kurzen /go/<game>-Link im Worker, der mit einem Referrer-Tag zu Google Play weiterleitet. So zeigt die Play Console die Installationen pro Quelle.
  • Analytics mit Einwilligung. Das Tag startet mit allen Speicherarten abgelehnt (Consent Mode v2) und schaltet sich erst ein, wenn der Besucher im Cookie-Banner zustimmt.
  • IndexNow nach jedem Deploy, damit Bing und Yandex Änderungen noch am selben Tag sehen.
  • Ein RSS-Feed pro Sprache, damit Feedreader und Aggregatoren die News finden.
  • Pressekits als ZIP-Dateien, von einem Skript aus den Spielgrafiken gepackt.

Was wir anders machen würden

Die Sprachliste und die Texttabellen vor dem HTML schreiben, nicht danach. 16 Sprachen nachträglich in Markup einzubauen, das von Englisch ausging, war der langsamste Teil des ganzen Projekts: Zeilenlängen, Schrift-Fallbacks für Japanisch, Koreanisch und Chinesisch und ein kyrillischer Fallback für Russisch brauchten jeweils einen eigenen Durchgang.

Die Spiele sind Idle Ronin: Cyber RPG, Idle Summoner: Pixel RPG, Block Brain und Idle AI Factory: Robot Tycoon, alle kostenlos bei Google Play.

Alle News

Alle News