Serie: Programmieren lernen mit KI

Spiele-Design im Hot-Reload wie Code

Experiences as code: ein diffbares JSON-Format mit Runtime-KI-Hooks.

Experiences as Code Eine .raku-Datei, jedes Tool, das du schon besitzt { "schema_version": "1.0", "ai": { "dda_enabled": true, "target_flow_state": 0.7 } } PR-Review CI-Validierung Hot Reload Runtime-KI Nervensystem, jeden Frame
Die Datei ist die Partitur. Die Runtime ist das Orchester.

Die meisten Engines liefern undurchsichtige Binärdateien aus. RakuAI liefert Text, den man diffen, reviewen und hot-reloaden kann — mit dem KI-Nervensystem direkt in der Datei adressierbar. Genau diese Entscheidung erlaubt es einem ganzen Team von Agenten, neben dir gemeinsam zu bauen.

Dateiformat-Wochenende. KI ist in dieser Engine ein Runtime-Primitiv, kein nachträglich angeflanschtes Feature. Das ist das architektonische Argument, das ich schon früher vorgebracht habe. Dieser Post handelt vom Dateiformat, das dieses Argument konkret macht.

Wenn du ein Spiel auf den meisten Engines baust, ist das Artefakt, das du ausliefertst, eine Binärdatei, ein Projekt-Bundle, eine Asset-Datenbank oder eine Kombination aus allen dreien. Was du erstellst, lebt in einem proprietären Editor. Was du ausliefertst, ist für die Tools, die dein Team bereits nutzt, undurchsichtig. Zwei Versionen einer Experience zu diffen bedeutet, denselben Editor zweimal zu starten und zu hoffen, dass das Änderungsprotokoll ehrlich ist.

Wir sind den anderen Weg gegangen. Eine RakuAI-Experience ist eine .raku-Datei. Die Datei ist JSON. Du kannst sie in jedem Editor öffnen. Du kannst zwei Versionen in jedem Code-Review-Tool diffen. Du kannst sie gegen ein Schema validieren. Du kannst sie in Git versionieren. Du kannst sie in einem PR reviewen. Du kannst sie hot-reloaden. Du kannst eine Experience von Hand schreiben, wenn du willst.

Das Dateiformat ist nicht glamourös. Es ist tragend.

Wie eine echte .raku-Datei aussieht

Hier ist eine echte Spieldefinition, für diesen Post gekürzt:

{
  "schema_version": "1.0",
  "game": {
    "title": "My Space Shooter",
    "genre": "space_shooter",
    "template": "space_shooter",
    "mode": "prototype",
    "max_players": 1
  },
  "ai": {
    "dda_enabled": true,
    "target_flow_state": 0.7,
    "profiler_mode": "active",
    "emotional_tracking": true,
    "adaptive_music": true
  },
  "entities": [
    {
      "type": "player_ship",
      "health": 100,
      "shield": 80,
      "speed": 22.0,
      "fire_rate": 0.09
    },
    {
      "type": "enemy_wave",
      "count": 8,
      "health": 15,
      "ai_behavior": "strafe",
      "properties": { "enemy_id": "interceptor" }
    },
    {
      "type": "boss",
      "health": 500,
      "ai_behavior": "boss_pattern"
    }
  ]
}

Das ist der Großteil einer Experience. Ein schema-versionierter Header. Ein game-Block mit den oberflächlichen Metadaten. Ein ai-Block mit der Runtime-KI-Konfiguration. Ein entities-Array, das beschreibt, was in der Welt existiert und wie sich jede Entität verhält.

Ein paar Dinge sind es wert, hervorgehoben zu werden.

Der ai-Block ist der Runtime-Vertrag

Schau dir diesen Teil noch einmal an:

"ai": {
  "dda_enabled": true,
  "target_flow_state": 0.7,
  "profiler_mode": "active",
  "emotional_tracking": true,
  "adaptive_music": true
}

Hier steht in der Datei: „Das KI-Nervensystem ist eingeschaltet.” Nicht „bitte GPT, mir ein Level zu schreiben.” Eingeschaltet. Auf der Runtime-Ebene, in jedem Frame, während der Spieler spielt.

dda_enabled schaltet die dynamische Schwierigkeitsanpassung ein. Die Runtime profiliert, was der Spieler tut, und formt Begegnungen im laufenden Betrieb um. target_flow_state: 0.7 ist die Schwierigkeitsband, auf das die Runtime abzielt. profiler_mode: "active" bedeutet, die KI liest das Verhalten des Spielers, sie sampelt es nicht nur. emotional_tracking und adaptive_music sind dieselbe Idee, angewandt auf andere Subsysteme.

Eine Engine im Factory-Pattern könnte diese Regler auf Dateiebene gar nicht haben. Es gibt dort keine Runtime-KI, die die Datei adressieren könnte. In unserer Engine sind diese Regler das Mittel, mit dem ein Autor dem Nervensystem mitteilt, welche Art von Experience es sein soll.

Du kannst diesen Block in einem PR reviewen. Du kannst zwei Werte in CI per A/B-Test vergleichen. Ein Produzent, der noch nie einen Editor gesehen hat, kann das lesen und mit dem Engineering darüber sprechen, was „target flow state” bedeutet. Das Dateiformat macht die Design-Entscheidung sichtbar.

KI-Verhalten pro Entität ist ein String, keine Integration

Jede Entität in der Datei kann ein ai_behavior-Feld tragen:

{
  "type": "enemy_wave",
  "count": 8,
  "ai_behavior": "strafe"
}

"strafe" ist kein Modellaufruf. Es ist ein registriertes Verhalten in der Runtime, das von der Nervensystem-Schicht gesteuert wird. Dieselbe Entität kann "patrol" oder "boss_pattern" sein oder alles andere, was die Runtime auszuführen weiß. Die Datei importiert kein Modell. Sie adressiert eine Fähigkeit.

So entkoppelt man das Dateiformat von einem konkreten Modell. Der Autor schreibt Absicht. Die Runtime entscheidet, welches Modell, welche Gewichte, welcher deterministische Fallback diese Absicht liefert. Tauscht man das Modell nächstes Quartal aus, ändern sich die .raku-Dateien nicht.

Diese Trennung ist wichtiger, als es klingt. Jedes Team, mit dem ich gesprochen habe, das ein spezifisches LLM fest in eine Engine eingebaut hat, musste die Integration neu machen, als der Modell-Anbieter wechselte. Wir müssen das nicht.

Warum JSON

Das ist die Frage, die ich am häufigsten gestellt bekomme, wenn ich das Dateiformat zeige. Warum JSON und nicht eine eigene DSL mit schönerer Syntax für mathematische Ausdrücke, Inline-Scripting und reaktive Bindings?

Drei Gründe.

Erstens: Jedes Tool spricht bereits JSON. Code-Review. Diff-Tools. Versionskontrolle. Linter. Schema-Validatoren. CI-Pipelines. Statische Analyse. Jeder Editor auf jeder Plattform. Wir mussten nichts davon selbst bauen. Wir haben es umsonst mitbekommen.

Zweitens: Menschen lesen JSON gut genug. Die Datei oben ist nicht schön, aber ein erfahrener Designer kann sie ohne Schulung lesen. Vergleiche das mit einer DSL, die eine Woche zum Lernen braucht, bevor überhaupt jemand einen PR reviewen kann.

Drittens: KI-Assistenten lesen JSON außerordentlich gut. Dieser Punkt zählt 2026 mehr als noch vor drei Jahren. Wenn ein Designer einen KI-Assistenten bittet, „den Boss furchteinflößender zu machen”, kann der Assistent die Datei lesen, einen Diff vorschlagen, und der Mensch kann den Diff annehmen oder ablehnen. Eine eigene DSL würde bedeuten, jedem Assistenten eine neue Grammatik beizubringen.

Die Kosten sind real. JSON ist wortreich. Es hat keine Inline-Mathematik, keine Kommentare, keine Kurzschreibweisen. Wir geben Ausdrucksstärke auf im Tausch gegen allgegenwärtiges Tooling. Bisher hat sich dieser Handel vielfach ausgezahlt.

Was das ermöglicht

Ein paar Dinge ändern sich, sobald deine Experience Text ist.

PR-Review für Spieldesign. Ein Designer ändert target_flow_state von 0.7 auf 0.5. Die Änderung erscheint als einzeiliger Diff in einem Pull Request. Engineering und Design reviewen die Änderung gemeinsam. Die Konversation im PR ist ein Protokoll dafür, warum sich die Experience so spielt, wie sie sich spielt. Sechs Monate später, wenn jemand fragt, warum sich die Schwierigkeitskurve so anfühlt, wie sie sich anfühlt, steht die Antwort im Commit-Log.

CI für Experiences. Eine .raku-Datei scheitert an der Schema-Validierung. Der Build schlägt fehl, bevor die Änderung ausgeliefert wird. Dieselbe CI, die deine Unit-Tests laufen lässt, lässt auch deine Experience-Definitionen laufen.

Hot Reload. Die Datei ändert sich auf der Festplatte. Die Runtime bemerkt es. Die Welt aktualisiert sich ohne Neustart. Der Entwicklungsloop verkürzt sich auf Sekunden.

Rollback. Eine Änderung hat den Bosskampf kaputt gemacht. Commit rückgängig machen. Die Experience macht die Änderung rückgängig. Kein Editor, kein Asset-Rebuild, kein wochenlanger Umweg.

Autoring durch KI. Ein Teammitglied beschreibt in natürlicher Sprache, was es möchte. Ein KI-Assistent schreibt den .raku-Diff. Ein menschlicher Reviewer genehmigt ihn. Der Diff ist auditierbar, versionierbar und unterliegt derselben Review-Disziplin wie jede andere Code-Änderung.

Das sind keine exotischen Fähigkeiten. Es ist das, was jedes moderne Softwareteam für den Rest seiner Codebasis für selbstverständlich hält. Wir haben es auf Spieledesign ausgeweitet.

Was schwierig ist

Die ehrlichen Kosten.

JSON hat keine Kommentare. Wir kompensieren mit begleitenden .md-Dateien für die Design-Absicht und mit beschreibenden Feldnamen, aber es bleibt echte Reibung.

Das Schema muss sich sorgfältig weiterentwickeln. Wir sind einmal von schema_version: 1.0 auf 2.0 gesprungen, als die Weltgenerierung die ursprüngliche Form übertroffen hat. Jede existierende Datei in freier Wildbahn brauchte einen Migrationspfad. Diese Arbeit gehört zum Job und ist nicht umsonst.

Es gibt die Versuchung, immer mehr Felder hinzuzufügen. Wir widerstehen ihr stärker, als es klingt. Jedes hinzugefügte Feld ist ein Vertrag, den die Runtime auf ewig einhalten muss. Die Neigung ist, die Datei klein zu halten und Komplexität in die Runtime zu verlagern, nicht in die Datei.

Und schließlich: textbasierte Experience-Definitionen sind nur relevant, wenn die Runtime tatsächlich etwas Interessantes damit anstellt. Das Dateiformat ist der Architekturentscheidung darunter nachgelagert. Wenn die Engine KI als Content-Fabrik behandelt, ist die Datei nur ein Manifest. Wenn die Engine KI als Runtime-Primitiv behandelt, ist die Datei die Partitur.

Wenn du das Format von Anfang bis Ende lesen willst: Das Schema liegt in der öffentlichen Dokumentation, und die Beispieldateien werden im Repo ausgeliefert. Öffne eine davon. Lies sie als Code, denn genau das ist sie.

Zwei Tage Dateiformat-Arbeit im Kasten. Nächstes Wochenende zurück an der Engine.

Erstelle Experiences, die deine KI lesen und schreiben kann

RakuAI behandelt KI als Runtime-Primitiv und Experiences als Code. Öffne das .raku-Format, diffe es, hot-reloade es — und lass deinen Assistenten mit dir in der realen Welt bauen.

← Alle Beiträge