Pocket Knight
Ein kleines Gerät im Hosentaschenformat. Es ist ein Mini Roguelike für unterwegs, bei dem man durch Schritte Fortschritt macht. Die Schritte, die man über den Tag sammelt schalten Events frei, wodurch man auf unterschiedliche Ereignisse und Kämpfe trifft. Mit jedem Kampf sammelt der Spieler Erfahrung, verbessert seine Ausrüstung und wird stärker.
Die Ereignisse werden gesammelt, sodass man sie abends in Ruhe nacheinander spielen kann und das Gerät nur tagsüber bei sich tragen muss. Etwas ausführlicher schreibe ich über den Entwicklungsprozess in diesem Blogbeitrag.
- Art
- Elektronik · Spiel
- Jahr
- 2026
- Details
- Status: spielbarer Prototyp

01 — Steckbrief
- Rolle
- Soloprojekt: Konzept, Elektronik, Firmware, Game Design, Pixelart und Gehäuse
- Zeitraum
- Rund 3 Monate in meiner Freizeit, 2026
- Werkzeuge
- C++ (Arduino IDE)
- U8g2
- Aseprite
- Fusion 360
- PrusaSlicer
- Prusa MINI+ (FabLab Kiel)
- Claude (AI assistant)
- Hardware
- DFRobot FireBeetle 2 ESP32-E
- SSD1306-OLED-Display, 128 × 64 px
- Seeed-Grove-Schrittzähler (BMA456)
- Passiver Piezo-Summer und Mini-Vibrationsmotor
- 3 Taster
- Li-Ionen-Akku mit 1800 mAh
- Lochrasterplatine, zweifarbiges Gehäuse aus PLA
02 — Idee
Ich wollte ein Gerät bauen, das an die Digivice-Spielzeuge aus meiner Kindheit erinnert: klein genug für die Hosentasche und mit einem Spiel, das beim Gehen vorankommt. Tagsüber bleibt das Gerät in der Tasche und zählt Schritte, abends spielt man die gesammelten Events in Ruhe durch.
Drei Anforderungen haben fast jede Entscheidung bestimmt: Das Gerät muss in eine Hosentasche passen, es muss wochenlang ohne Laden auskommen, und es muss den ganzen Tag Schritte zählen, ohne dass jemand es bedient. Die letzten beiden widersprechen sich: Dauerhaftes Zählen kostet Strom, eine lange Laufzeit verlangt, dass der Prozessor fast immer schläft.
03 — Vorgehen
Ich habe einen FireBeetle 2 ESP32-E gewählt, weil das Laden des Akkus schon auf dem Board passiert und ich nur noch eine Li-Ionen-Zelle anschließen musste. Für die Schritte nutze ich einen BMA456, der Schritte selbstständig in der Hardware zählt. Zuerst lief alles auf einem Breadboard, darauf habe ich den Großteil der Firmware geschrieben.
Als Schaltung und Code stabil waren, habe ich alle Teile möglichst kompakt auf eine Lochrasterplatine gelötet und danach Spielablauf, Inhalte und Sprites verfeinert, bis es sich wie ein vollständiges Spiel anfühlte.

04 — Schritte zählen im Schlaf
Die Lösung für den Widerspruch oben ist, die Arbeit zu teilen. Der BMA456 zählt die Schritte durchgehend selbst, und der ESP32 geht nach 30 Sekunden ohne Eingabe in den Deep Sleep. Taste A weckt ihn wieder.
Was zuerst schiefging: Der Schrittzähler hat aufgehört zu zählen und sich zurückgesetzt, sobald er keine Stromversorgung hatte. Sein Zählerstand lag danach unter dem Wert, den das Spiel zuletzt gespeichert hatte.
So funktioniert es jetzt:
- Beim Start prüft die Firmware, warum das Gerät startet. Nach einem Kaltstart richtet sie den Sensor ein und speichert 0 als neuen Bezugswert. Nach dem Aufwachen aus dem Deep Sleep richtet sie ihn bewusst nicht neu ein, weil das seinen Zähler zurücksetzen würde.
- Ins Spiel geht nur die Differenz zum gespeicherten Zählerstand. Ist der neue Wert kleiner, erkennt die Firmware einen Reset und setzt nur den Bezugswert neu, statt Schritte abzuziehen.
- Schlägt das Auslesen über I²C fehl, gibt die Funktion den letzten bekannten Wert zurück. Ein Lesefehler kommt so nie als Schrittsprung im Spiel an.
Vereinfachter Ausschnitt aus progress.ino:
void syncSteps() {
uint32_t cur = readSensorSteps(); // Zählerstand des BMA456
if (cur > lastSensorSteps) {
addSteps(cur - lastSensorSteps); // nur die Differenz zählt
lastSensorSteps = cur;
} else if (cur < lastSensorSteps) {
lastSensorSteps = cur; // Sensor wurde zurückgesetzt
}
}

05 — Pixelgrafik
Alle Sprites habe ich in Aseprite als 1-Bit-Pixelart gezeichnet. Schwierig war der Weg aufs Display: Jede Grafik musste ins XBM-Format umgewandelt werden, und die Animationen werden direkt im Code gesteuert, der Bild für Bild festlegt, was gezeichnet wird. Gezeichnet wird mit der Bibliothek U8g2, die Bitmaps liegen per PROGMEM im Flash statt im knappen Arbeitsspeicher.
Rückblickend hätte eine Bibliothek oder ein kleines Werkzeug für Sprite-Animationen viel Handarbeit gespart.

06 — Firmware
Die Firmware ist in C++ in der Arduino IDE geschrieben und in Module aufgeteilt: Kampf, Events, Fortschritt und Speichern, Darstellung und Audio.
- Zustandsautomat: Jeder Bildschirm ist ein eigener Zustand. Die Hauptschleife ruft die passende Funktion für Eingabe und Darstellung auf; der Kampf hat eigene Phasen (wählen, auswerten, Ergebnis, Gegenstandswahl).
- Kein doppelter Tastendruck: Taste A weckt das Gerät und bestätigt im Menü. Damit derselbe Druck nicht sofort eine Aktion auslöst, ignoriert die Firmware nach dem Aufwachen alle Eingaben, bis jede Taste einmal losgelassen wurde.
- Immer gespeichert: Der Fortschritt wird an jedem Checkpoint und vor dem Einschlafen in den Flash-Speicher geschrieben, getrennt nach aktuellem Durchlauf und dauerhaftem Fortschritt. Jeder Spielstand trägt eine Versionsnummer; passt sie nicht zur Firmware, wird er verworfen statt falsch gelesen.
- Inhalte als Daten: Gegner, Gegenstände, Freischaltungen und Event-Gewichte stehen als Tabellen oben im Code. Zum Balancing muss ich die Logik nicht anfassen.

07 — Spielmechanik und Balancing
Im Schnitt alle 300 Schritte (zufällig zwischen 220 und 380) kommt ein neues Event dazu. Ist das Gerät in dem Moment wach, piept und vibriert es. Bis zu 10 Events werden gespeichert, sodass man sie später am Stück spielen kann. An jeder Weggabelung wählt man eins von zwei Events, von Kämpfen und Händlern bis zu Fallen, Schreinen und einem Wunschbrunnen.
Die Kämpfe sind rundenbasiert: Der Gegner zeigt seinen nächsten Zug vorher an, und der Spieler antwortet mit Angriff, Block, einer von 5 Fähigkeiten oder einem Verbrauchsgegenstand. Nach jeweils 10 Events wartet ein Boss; wer den vierten besiegt, gewinnt den Durchlauf. Insgesamt gibt es 7 Gegnertypen mit eigenem Verhalten und 22 Gegenstände. Endet ein Durchlauf, schalten Meta-Punkte dauerhafte Startboni frei.
Balancing: In der ersten Fassung kam alle 250 Schritte ein Event, und bis zu 20 konnten sich ansammeln. Das machte die Session am Abend mühsam. Mit etwas mehr Schritten pro Event und höchstens 10 gespeicherten Events bleibt der Abend kurz, und ein Durchlauf mit 40 Events dauert ungefähr eine Woche.
08 — Gehäuse
Das Gehäuse habe ich in Fusion 360 entworfen und im FabLab Kiel auf einem Prusa MINI+ zweifarbig gedruckt: grau für den Körper, blau für den Displayrahmen und die Lilien-Embleme. Eine kleine Münze mit dem Emblem dient als Schlüsselanhänger. Nach dem ersten Druck gab es eine Überarbeitung, in der ich nur die Tiefe des Gehäuses leicht angepasst habe.
Druckdateien und Slicer-Einstellungen liegen im GitHub-Repository, sodass sich das Gerät nachbauen lässt.

09 — Ergebnis
Pocket Knight ist ein spielbarer Prototyp: ein kompletter Durchlauf mit 11 Eventarten, 7 Gegnertypen, 4 Bossen, 22 Gegenständen und dauerhaftem Fortschritt über mehrere Durchläufe, in rund 3.700 Zeilen Firmware. Das Gerät ist seit Wochen im Alltag im Einsatz. Im Hauptmenü steckt noch ein Debug-Eintrag zum Testen; da es nur dieses eine Gerät gibt, bleibt der Status bei Prototyp.
Die Laufzeit habe ich über die Akkuanzeige des Geräts abgeschätzt: Je eine Woche im normalen Betrieb und im Standby habe ich beobachtet, wie weit die Prozentanzeige sinkt, und das hochgerechnet. Daraus ergeben sich etwa 3–4 Monate pro Akkuladung. Firmware, Gehäusedateien und Artwork sind unter MIT-Lizenz offen.

10 — Was ich gelernt habe und ändern würde
- Energie gegen Spielgefühl: Der Deep Sleep sichert die Laufzeit, kostet aber eine Funktion. Neue Events melden sich mit Piepen und Vibration nur, solange das Gerät wach ist. In der Tasche schläft es fast immer, deshalb sammeln sich die Events still an. Der nächste Schritt ist, den Interrupt des BMA456 als zweite Weckquelle zu nutzen.
- Kleinerer Akku: 1800 mAh reichen für Monate, sind aber das schwerste Bauteil. Beim nächsten Mal würde ich zuerst die gewünschte Laufzeit festlegen und den Akku danach wählen.
- Genauere Akkuanzeige: Die Prozentanzeige rechnet die Spannung linear um. Li-Ionen-Zellen entladen sich aber nicht linear, deshalb ist auch die Laufzeit-Schätzung nur grob. Eine Tabelle mit der echten Entladekurve wäre genauer.
- Inhalte für das Display entwerfen: 128 px Breite reichen nicht für jeden Text. Manche Texte werden abgeschnitten, und einige Mechaniken erklärt das Spiel zu wenig.
- Werkzeuge für Grafiken: Für Sprites und Animationen würde ich von Anfang an eine Bibliothek oder ein eigenes Export-Skript nutzen.
Vorerst gestrichen: Koop- und Versus-Multiplayer über ESP-NOW, eine Online-Bestenliste, flüssigere Animationen, weitere Startklassen und eine englische Fassung der Spieltexte.
11 — Medien
Das Video wird erst nach dem Klick von YouTube geladen.
12 — Galerie (01)
Fragen, Ideen oder Feedback? Ich freue mich über eine Nachricht.
Schreib mir