Claude Sonnet speelt DOOM op SCINTIX P4

Projectbeschrijving

DOOM is geporteerd naar de SCINTIX P4 (een module bestaande uit een ESP32-P4 en een ESP32-C6 in de vormfactor van een Raspberry Pi CM4/CM5). Het spel draait op een 1024×600 MIPI-DSI-paneel en wordt door de PPA (Pixel-Processing Accelerator) van de P4 hardwarematig geschaald naar 30 FPS.

Om het spel toegankelijk te maken voor een LLM, is er een kleine WebSocket "lockstep" API en een MCP-server ontwikkeld. De AI-agent is bewust beperkt tot de informatie die een menselijke speler ziet:

  • Een raycast-diepte-waaier over het gezichtsveld.
  • Vijanden op het scherm die zich in de directe zichtlijn bevinden.
  • Een ASCII-automap van ontdekte muren.
  • Aanwijzingen zoals "deur voor je" (door_ahead) en "je bent geblokkeerd" (blocked).

De agent stuurt op basis hiervan commando's voor bewegen, draaien, vuren en het gebruiken van objecten. Het project is volledig open source.

Technische Details

Hardware-setup

De SCINTIX P4 is een system-on-module met de volgende specificaties:

  • Processor: ESP32-P4 (dual-core RISC-V @ 400 MHz, MIPI-DSI, 2D pixel-processing accelerator, USB).
  • Connectiviteit: ESP32-C6 voor Wi-Fi en BLE.
  • Vormfactor: Raspberry Pi CM4/CM5.
  • Beeld: 1024x600 DSI-paneel. Het 320x200 frame wordt door de PPA van de P4 geschaald naar volledig scherm via een zero-copy page-flip, wat resulteert in een stabiele ~30 FPS.
  • Input: USB-toetsenbord of gamepad.
  • Audio: ES8311 codec.

AI-besturing en de MCP-server

Het interessante aspect is hoe het model het spel aanstuurt. De firmware draait het spel in lockstep:

  1. De agent stuurt een actie.
  2. Het spel vordert een paar 'tics'.
  3. De agent ontvangt een gestructureerde observatie.
  4. Het spel pauzeert tot de volgende actie.

Dit determinisme zorgt ervoor dat het model redeneert over een bevroren, coherent frame in plaats van een scène die blijft bewegen terwijl de AI nadenkt. Dit verklaart ook waarom de bewegingen van de marine in de video schokkerig verlopen.

Een kleine MCP-server (Model Context Protocol) fungeert als tussenlaag. Hierdoor kan elke MCP-compatibele client (zoals Claude Code) het spel registreren als een set tools:

  • observe
  • moveforward / moveback
  • turnleft / turnright
  • strafeleft / straferight
  • fire
  • use
  • select_weapon
  • get_map

Visuele Perceptie en "Eerlijk Spelen"

Om te voorkomen dat het model "spiekt" in de speldata, krijgt het alleen informatie die visueel afleidbaar is:

  • Raycast-waaier: Een waaier van 51 stralen over het gezichtsveld (de "diepte" van het gerenderde beeld) om afstanden in te schatten en openingen te spotten. In een eerdere versie met slechts 7 stralen liep de agent vaak tegen muren aan omdat openingen tussen de stralen vielen.
  • Zichtbare objecten: Alleen vijanden en items die daadwerkelijk op het scherm staan en in de zichtlijn liggen (van links naar rechts), nooit door muren heen.
  • ASCII-automap: Toont enkel de muren die al zijn ontdekt, vergelijkbaar met de in-game map.
  • Contextuele hints:
  • door_ahead: Geeft aan dat er een gesloten deur in beeld is (zodat een dichtslaande deur wordt herkend als "gebruik opnieuw" in plaats van een massieve muur).
  • blocked: Geeft aan dat de laatste beweging geen vooruitgang heeft geboekt.

Ontwikkeling en Probleemoplossing

Navigatie-bugs

In het begin verwisselde het model constant links en rechts. Dit kwam doordat de gerapporteerde koersingen (bearings) tegenovergesteld waren aan de documentatie en de kijkhoek niet overeenkwam met de map. Door overal de conventie positief = rechts toe te passen en de koers af te stemmen op een noord-georiënteerde automap, begon de agent correct te navigeren.

Draadloze connectiviteit

Omdat de ESP32-P4 geen eigen radio heeft, wordt de draadloze communicatie afgehandeld door de ESP32-C6 via een 4-bit SDIO-link (ESP-Hosted). Bij de eerste boot start er een captive portal (SSID SCINTIX-P4-xxxx) voor het instellen van netwerkgegevens. Er wordt daarnaast geëxperimenteerd met een native-BLE controller om bijvoorbeeld een 8BitDo Micro zonder USB-dongle te koppelen.

USB en Audio

  • USB Host: Toetsenborden en HID-gamepads worden direct aangesloten. Een belangrijke ontdekking was dat full-speed apparaten achter een high-speed hub een Transaction Translator (TT) vereisen, wat niet is geïmplementeerd in de gebruikte IDF USB-host stack. Apparaten moeten daarom direct worden aangesloten.
  • Audio: Er is een externe ES8311 codec (M5 Atomic EchoBase) gebruikt via I2S. Omdat de EchoBase geen externe MCLK heeft, wordt de klok afgeleid van de bit clock (use_mclk = false). Bij 22050 Hz / 16-bit is de interne multiplier correct.

Optimalisatie naar 30 FPS

Het opschalen van de 320x200 resolutie naar 1024x600 via de CPU was de grootste bottleneck (ongeveer 24 ms per frame), wat de snelheid beperkte tot 20 FPS. Door gebruik te maken van de 2D Pixel-Processing Accelerator (PPA) van de ESP32-P4, werd deze tijd teruggebracht naar ongeveer 9 ms.

Er trad echter een bug op waarbij de PPA de schaalfactor kwantiseerde in stappen van 1/16. Hierdoor werd het beeld 1020 pixels breed in plaats van 1024, wat leidde tot flikkerende kolommen aan de rechterzijde. Dit is opgelost door beide framebuffers bij opstarten zwart te maken, waardoor er een onzichtbare zwarte rand van 4 pixels ontstaat.

Gebruikte Componenten

  • SCINTIX P4: ESP32-P4 + ESP32-C6 system-on-module in Raspberry Pi CM4/CM5 vormfactor.
  • Raspberry Pi CM5 (CM4) I/O Board: Carrier board voor MIPI-DSI display, USB, Ethernet en GPIO.
  • 7" 1024x600 MIPI-DSI panel: Display uit de Espressif ESP32-P4-Function-EV-Board kit.
  • MIPI-DSI adapter FFC kabel: Voor de aansluiting tussenHet carrier board en het paneel.
  • M5 Atomic EchoBase (ES8311): I2S audio codec module voor geluidseffecten.

Bronnen