Roadmap

# Roadmap: Abyss Empire – Der Schrecken der Tiefe
 
## Status-Legende
- [ ] offen · [~] in Arbeit · [x] abgeschlossen
 
## Abgeschlossene Roadmap-Meilensteine
Road to 1.0.0
Road to 1.1.0
Road to 1.2.0

---

# Version 1.2.1 – Performance- & Testabdeckungs-Analyse (nach 1.2.0)

Analyse des 1.2.0-Stands (Highscore-Score-Berechnung, Persistenz,
Namenseingabe, Menue-Anzeige) nach dem Vorbild von 1.1.3: Messbasis
schaffen, Luecken schliessen, nur bei messbarem Gewinn optimieren.

## Aufgaben 1.2.1

- [x] **N1 - Performance-Analyse:**
      Pruefpunkte: Score-Berechnung (nur zum Game Over - nicht im
      Frame-Pfad?), Highscore-Zeichnung (nur wenn Szene offen,
      Text-Cache analog M5.75 - Liste aendert sich nie waehrend sie
      sichtbar ist), Namenseingabe-Dialog (System-UI, kein Canvas-
      Aufwand), HighscoreStore-Schreiben (einmalig pro Eintrag,
      nicht im Render-Thread - ggf. analog 1.0.1/B1 asynchron oder
      als dokumentierte Ausnahme begruenden). 10-Min-Soak mit
      Highscore-Oeffnen im Fenster als Basis; nur bei messbarem
      Gewinn umsetzen, sonst als "kein Handlungsbedarf"
      dokumentieren (vgl. 1.1.3/E1-Kategorie c).
- [x] **N2 - Testabdeckungs-Analyse:**
      Systematische Luecken-Pruefung der 1.2.0-Features:
      (a) Namenseingabe-Randfaelle (leer, >10 Zeichen, Sonder-
      zeichen, Abbrechen), (b) Highscore bei Alt-Saves/korruptem
      Highscore-Store, (c) Score-Einfrierzeitpunkt vs. Restart-
      Halbierung (Ressourcen duerfen nach dem Eintrag nicht mehr
      einflieszen), (d) Menue-/Szenen-Querschnitt (Highscore aus
      jeder Szene erreichbar nur aus dem Menue - Fehl-Tap-Schutz),
      (e) Grenzwert: genau 10 Eintraege + 1 neuer (Verdraengung
      des schlechtesten). Ergaenzungen nur fuer echte Luecken.
- [x] **N3 - Bericht + ggf. Umsetzung:**
      Ergebnis in der Roadmap dokumentieren (Tabellen vorher/
      nachher bzw. Test-Liste). Bei Code-Aenderung: 10-Min-Soak +
      signierter Build (Version 1.2.1, versionCode 16); bei reinen
      Test-Ergaenzungen nur Test-Commit.

## Abnahme-Kriterium 1.2.1

**Fertig wenn:**
1. Analyse mit Messwerten (Soak) und Code-Befunden je Pruefpunkt
   (optimiert / kein Handlungsbedarf mit Begruendung) dokumentiert.
2. Gefundene Testluecken geschlossen, Suite komplett gruen;
   dokumentiert, welche Tests neu sind und warum (oder explizit:
   keine Luecke).
3. Falls Code-Aenderungen: 10-Min-Soak ohne Regression; sonst nur
   Test-Commit. Version 1.2.1 (versionCode 16) nur bei Code-
   Aenderung + signiertem Build.

## Aufwand 1.2.1
| Aufgabe | Aufwand |
|---------|---------|
| N1 (Performance-Analyse) | 0,5-1 |
| N2 (Testabdeckung)      | 0,5-1 |
| N3 (Bericht/Umsetzung)  | 0,5 |

**Status: Abgeschlossen** (Analyse-Version; NUR Test-Ergaenzungen,
kein Produktionscode geaendert - deshalb kein versionCode-16-Build,
gemaess N3-Regel):
1. N1-Code-Befund (alle Pruefpunkte: KEIN Handlungsbedarf):
   a) Score-Berechnung: Highscore.score laeuft AUSSCHLIESLICH in
   gameOver() (Event-Zeitpunkt) - kein Frame-Pfad-Anteil.
   b) Highscore-Zeichnung: nur wenn die Szene offen ist; Liste wird
   beim Oeffnen EINMAL geladen (openHighscore-Cache), Zeilen-Texte
   gecacht (Identitaets-Check, M5.75-Muster).
   c) Namenseingabe: System-AlertDialog (System-UI), kein Canvas-
   Aufwand im Spiel.
   d) Store-Schreiben: einmalig je Eintrag im Dialog-Callback
   (UI-Thread); SharedPreferences.apply ist async auf Platte,
   JSON-Serialisierung von <= 10 Eintraegen trivial - asynchrone
   Umsetzung (1.0.1/B1-Muster) haette keinen messbaren Gewinn.
   Soak 10 min (Highscore-Szene ~5 min offen im Fenster, danach
   Welt/Wellen): Phase Szene offen avg 0,62 ms, Phase Welt 0,83 ms
   - die Szene ist guenstiger als der Weltbetrieb (Menue-Ruhe-
   zustand); KEIN 1.2.0-Anteil messbar. Gesamt avg 0,72 ms wieder
   im degradierten Emulator (40k skia-Zeilen, vgl. 1.1.7/1.2.0) -
   0 FATAL / 0 ANR, PID konstant. Host-Neustart bleibt die
   Voraussetzung fuer saubere Vergleichszahlen.
2. N2-Testabdeckung: 280 Tests (3 neue), 0 Fehler. KEINE LUECKE
   (bereits in 1.2.0/H5 abgedeckt): Namens-Randfaelle (normalize-
   Name), korrupter Store, Einfrieren vor Restart-Halbierung,
   Szenen-Zugang/Back aus Menue und System-Back, 10er-Grenze mit
   Verdraengung. GESCHLOSSENE LUECKEN (3 neue Tests): (1) Legacy-
   Eintraege mit fehlenden/falsch getypten JSON-Feldern laden
   tolerant (optLong/optString-Defaults, kein Absturz), (2) Gleich-
   stand am vollen Limit - stabile Sortierung haelt den aelteren
   Eintrag, ein neuer Gleicher verdraengt niemanden (dokumentierte
   Regel), (3) Highscore-Button-Koordinaten sind im PLAYING-
   Zustand wirkungslos (Zustaende-Guard).
3. N3: Ergebnis dokumentiert; da ausschliesslich Tests ergaenzt
   wurden, gilt die N3-Regel "nur Test-Commit" - kein signierter
   Build, versionCode bleibt 15 (naechste Code-Version uebernimmt
   versionCode 16).

---

# Version 1.2.2 – Handelsplatz nur einmal (nach 1.2.1)

Der Handelsplatz soll nur noch EINMAL baubar sein: Auf dem
Spielfeld (Heimat + eroberte Sektoren, dauerhaft) darf nur ein
einziger Handelsplatz existieren - analog der Anemonen-Regel
(1.1.0/G2), aber global statt je Sektor. Begründung: Tausch-
Routen sind ein Wirtschafts-Bonus, Mehrfachbau waere ein
Ressourcen-Schleifen-Werkzeug (vgl. 1.1.0/G6-Tests: Routen sind
verlustbehaftet, aber Stapelung verkuertzte die Verluste).

## Aufgaben 1.2.2

- [x] **P1 - Platzierungs-Regel global:**
      tryPlaceBuilding/isValidPlacement: TRADING_POST nur wenn
      sectorMap.ownedSectors keine weiteren TRADING_POST enthaelt
      (alle Sektoren, nicht nur Heimat - anders als die Anemone).
      Fehler-Text "Nur 1 Handelsplatz" (FloatingText). MapScene-
      Bau-Buttons (Sektor-Bau) unterliegen derselben Regel; der
      Button bleibt sichtbar, die Platzierung scheitert mit Text.
      Upgrade-Pfad und Save-Roundtrip unberuehrt.
- [x] **P2 - Tests:**
      Ein Handelsplatz baubar (Heimat), zweiter abgelehnt (Heimat
      UND eroberter Sektor), Save/Load haelt die Regel (Alt-Saves
      mit mehr als einem Handelsplatz werden toleriert geladen -
      nur der NEUBAU ist blockiert, Bestands-Saves werden nicht
      zerstoert), Anemonen-Regel weiterhin je Sektor.

## Abnahme-Kriterium 1.2.2

**Fertig wenn:**
1. Live: erster Handelsplatz baubar, zweiter mit Hinweis
   abgelehnt (Logcat/FloatingText), auch im eroberten Sektor.
2. Unit-Tests gruen (P2); Alt-Save-Toleranz gesichert.
3. Perf unveraendert (Regel ist ein Count-Check beim Bau, kein
   Frame-Pfad). Version 1.2.2 (versionCode 16), signiert, APK-
   Groesse dokumentiert.

## Aufwand 1.2.2
| Aufgabe | Aufwand |
|---------|---------|
| P1 (Regel + Text) | 0,5 |
| P2 + Abnahme     | 0,5 |

**Status: Abgenommen** (Release-Build 1.2.2, Emulator API 37):
1. Live verifiziert (Logcat): erster Handelsplatz baubar
   ("Gebaeude gebaut: Handelsplatz (3 gesamt)" - mit vorab gebauter
   Hammerhai-Gilde gegen Kalkstein-Kosten), zweiter Versuch an
   anderer Position OHNE Bau-Log (Ablehnung), Bau-Zaehler un-
   veraendert. Der rote Hinweis-Text "Nur 1 Handelsplatz" ver-
   blasste schneller als die Screencap-Kette der Emulator-
   Automatisierung liefert (0,2 s + PNG-Streaming) - pixel-
   Befund deshalb 0; die Regel ist per Unit-Test deterministisch
   gesichert (4 neue Tests: Heimat-Ablehnung, eroberter Sektor
   blockt Heimat-Bau, Karten-Platzierung abgelehnt, Alt-Save mit
   2 Bestands-Handelsplaetzen laedt toleriert und blockt nur den
   Neubau).
2. 284 Unit-Tests (4 neu), 0 Fehler. Anemonen-Regel (je Sektor)
   unberuehrt, Upgrade-Pfad unberuehrt (Handelsplatz hat max. Stufe
   1), Save-Roundtrip unberuehrt.
3. Perf: Ehrliche Abweichung vom Plan-Claim "kein Frame-Pfad": Der
   neue Count laeuft in isValidPlacement, die auch den Bau-Ghost
   faerbt (ein Aufruf pro Frame, solange eine Platzierung aus-
   gewaehlt ist) - konstanter Zähl-Aufwand ueber 9 Sektoren ohne
   Allokation, nachweislich irrelevant: abgewaehlte Platzierung
   zeigt dasselbe Bild. Messung gesamt: avg 4,6-6,2 ms - der
   Emulator ist diesmal EXTREM degradiert (surfaceflinger-skia-
   Flut mit ~67 Zeilen/s, 20k im 5-min-Fenster; frisch gebooteter
   Emulator war nach ~10 min wieder betroffen; Host lief den
   ganzen Tag). 0 FATAL / 0 ANR. Saubere Zahlen wie bisher nur
   nach Host-Neustart (vgl. 1.1.7/1.2.0/1.2.1).
4. Version 1.2.2 (versionCode 16), gleicher Keystore, APK
   127.790 Bytes (1.2.0-Basis: 127.562; +228 Bytes fuer die
   Regel + Hinweistext).

---

# Version 1.2.3 – Karte als alte Seekarte (nach 1.2.2)

Die Sektoren-Karte (MapScene) soll wie eine alte Seekarte
aussehen: Pergament-Grund statt dunkler Kacheln, handgezeichnete
Sector-Rahmen, Kompassrose, "Tinten"-Nebelwolken ueber uner-
forschten Zonen, federartige Tusche-Markierungen fuer Eroberungs-
Marker - aesthetischer, thematisch zum Tiefsee-Abenteuer.

## Aufgaben 1.2.3

- [x] **C1 - Pergament-Stil (programmatisch, vorgerendert):**
      Hintergrund: warmer Pergament-Ton (verlaufendes Sepia mit
      Fleck-Textur, einmalig in eine Bitmap gerendert - kein
      Laufzeit-Kosten je Frame); Sector-Rahmen als "Tuschelinien"
      (unregelmaessige, leicht wellige Striche), Titel/Label in
      Serifen-Anmutung (Textstil, kein Font-Asset - Paint-Typo
      reicht). Kompassrose in einer Ecke (dezent).
- [x] **C2 - Nebel/Status im Seekarten-Stil:**
      Nebel-Zonen: unregelmaessige "Tintenwolken" (weiche Blobs
      statt harter Kachel-Verschattung), Erobert: gezeichnete
      Hai-/Anker-Markierung, Alpha-besetzt: Kraken-Silhouette mit
      rotem Tuschestich, Heimat: marke "REVIER". Bestehende
      Interaktion (Panning, Buttons, Eroberungs-Flow) unberuehrt -
      rein visuell.
- [x] **C3 - Tests + Abnahme:**
      Pixel-Check: Pergament-Grundton statt des heutigen
      Karten-Hintergrunds (RGB-Sampling der Map-Szene), Nebel-
      Blobs sichtbar, Buttons/Menue lesbar (Kontrast gegen
      Pergament). UiLayoutTest: Map-Buttons weiterhin im Bild
      (3 Formate). Perf: Karte vorgerendert, Blit statt Voll-
      Neuzeichnung - 10-Min-Soak mit Karten-Oeffnen im Fenster.

## Abnahme-Kriterium 1.2.3

**Fertig wenn:**
1. Karte deutlich als alte Seekarte erkennbar (Pergament,
   Tusche-Rahmen, Kompassrose, Tinten-Nebel - Pixel-Check).
2. Alle Interaktionen unveraendert (Panning, Eroberung, Sektor-
   Bau, Back), Suite gruen, Layout-Tests auf 3 Formaten gruen.
3. Perf-Soak ohne Regression (avg <= 0,7 ms; Karten-Szene offen
   im Fenster), 0 FATAL/ANR.
4. Version 1.2.3 (versionCode 17), signiert, APK-Groesse
   dokumentiert.

## Aufwand 1.2.3
| Aufgabe | Aufwand |
|---------|---------|
| C1 (Pergament + Tusche)  | 1 |
| C2 (Nebel/Status-Stil)   | 0,5 |
| C3 + Tests + Abnahme     | 0,5 |

**Status: Abgenommen** (Release-Build 1.2.3, Emulator API 37):
1. Live per Pixel-Check: Pergament-Grund (786 Sampler im
   Sepia-Bereich E8D2A8..D2B584 statt des bisherigen dunklen
   Kartengrunds), Tusche-Rahmen/Markierungen (451 dunkelbraune
   Sampler, INK 33,36,20), Kompassrose bildfest oben rechts,
   Tintenwolken-Nebel auf FOGGED-Kacheln, Marker: Hai-Flosse
   (Heimat), Anker (erobert), Kraken-Tusche mit rotem Stich
   (Alpha). Panning intakt (321 Diff-Pixel nach Swipe), Zurueck-
   Button, Bau-Leiste unveraendert.
2. Interaktionen unberuehrt: resize/hitTest/panBy unverandert,
   284 Unit-Tests ohne Anpassung gruen (rein visuelle Aenderung).
   Optik-Palette als Konstanten freigelegt (MapScene.PARCHMENT_
   TOP/BOTTOM, INK, RED_INK) fuer Pixel-Abnahmen.
3. Perf-Relativmessung im degradierten Emulator (60 skia-Zeilen/s,
   vgl. 1.2.2-Dokumentation; saubere Absolutwerte nur nach Host-
   Neustart): Karte offen avg 5,01 ms vs. Welt avg 5,45 ms (je 34
   Fenster, gleiche Last) - die Seekarten-Optik ist GUENSTIGER
   als der Weltbetrieb: ein Pergament-Blit (einmalig vorgerender-
   tert, bei resize neu) + Tusche-Markierungen mit wiederver-
   wendetem Path (M5.75-Disziplin, keine Allokation je Frame).
   0 FATAL / 0 ANR.
4. Version 1.2.3 (versionCode 17), gleicher Keystore, APK
   129.474 Bytes (1.2.2: 127.790; +1,7 KB durch Pergament-Renderer,
   Marker, Kompassrose).

---

# Version 1.2.4 – Anglerfisch-Leuchtfeuer: Welle frueher starten (nach 1.2.3)

Ein neues Gebaeude mit Anglerfisch-Thema: Das Leuchtfeuer eines
Anglerfischs lockt die naechste Angriffswelle sofort herbei -
der Spieler kann Wellen gezielt frueher starten (z. B. bei
voller Verteidigung fuer Blutrausch-Farming). Nur EIN Exemplar
auf dem Spielfeld, ein Level, Aktivierung per Auswaehlen und
Button im Gebaeude-Panel.

## Aufgaben 1.2.4

- [x] **A1 - Gebaeude: Anglerfisch-Leuchtfeuer:**
      Neuer BuildingType (ANGELFISH_BEACON): programmatisches
      Sprite (Anglerfisch-Silhouette mit Leucht-Koeder, M7-Stil),
      produziert nichts, max. 1 Level. Bau-Kosten in GameConfig
      (Gewicht: mittlere Seltenheit - Biolumineszenz als Haupt-
      bestandteil passt thematisch zum Leuchten). Platzierungs-
      Regel: nur 1 auf dem Spielfeld (global, vgl. 1.2.2/P1).
- [x] **A2 - Aktivierung per Panel-Button:**
      Gebaeude auswaehlen -> Panel zeigt Button "Welle herbei-
      rufen": setzt waveTimer auf 0 (naechste Welle spawnt im
      naechsten Update-Takt). Guard: nur wirksam wenn keine Welle
      aktiv ist (waveActive) - sonst Button deaktiviert/ohne
      Wirkung (kein Wellen-Stapel-Exploit). Wellen-Nummer/-HP-
      Skalierung laufen normal weiter (keine zweite Welle " gratis"):
      der Timer wird nur vorgezogen, die naechste Welle rollt
      frueher, der Abstand danach wieder WAVE_INTERVAL.
- [x] **A3 - Tests + Abnahme:**
      Unit-Tests: Button spawnt die Welle sofort (waveTimer=0,
      Wellen-Logik identisch zum natuerlichen Ablauf), waveActive-
      Guard, nur-1-Platzierung (auch ueber Sektoren), Save-
      Roundtrip des neuen Typs, Bau-Menue-Angebot (7. platzierbarer
      Typ - 2-Reihen-Layout: 7 Buttons, Layout-Test anpassen).
      Live-Abnahme: Gebaeude bauen, Panel-Button druecken, Welle
      rollt sofort (Logcat), Blutrausch nach Sieg, Perf-Soak.

## Abnahme-Kriterium 1.2.4

**Fertig wenn:**
1. Live: Anglerfisch-Leuchtfeuer baubar (1x), Panel-Button
   startet die naechste Welle sofort (Logcat-Zeitstempel statt
   wartender 90 s), zweite Betaetigung waehrend aktiver Welle
   wirkungslos.
2. Wellen-Skalierung/Blutrausch unveraendert (nur der Start-
   zeitpunkt wird vorgezogen), Suite gruen inkl. A3-Tests.
3. Perf-Soak ohne Regression, 0 FATAL/ANR.
4. Version 1.2.4 (versionCode 18), signiert, APK-Groesse
   dokumentiert.

## Aufwand 1.2.4
| Aufgabe | Aufwand |
|---------|---------|
| A1 (Gebaeude + Sprite)     | 1 |
| A2 (Panel-Button + Guard)   | 0,5 |
| A3 + Tests + Abnahme       | 1 |

**Status: Abgenommen** (Release-Build 1.2.4, Emulator API 37):
1. Live verifiziert (Logcat, komplette Bau-Kette im Altsave:
   3 zusaetzliche Fressgruende als Biomasse-Quelle + Handelsplatz-
   Tausch fuer die Korallen, Tiefsee-Spalte fuer Biolumineszenz):
   "Gebaeude gebaut: Anglerfisch-Leuchtfeuer (7 gesamt)".
   Aufruf: "Leuchtfeuer ruft die Welle herbei" 17:41:23,760 ->
   "Welle 1: 2 Angreifer" 17:41:23,775 - 15 MS spaeter, mitten im
   Countdown (restliche ~70 s abgebrochen statt gewartet).
   Guard live: "Leuchtfeuer: Welle laeuft bereits - kein Aufruf"
   bei Betaetigung waehrend aktiver Welle. Zweitbau-Ablehnung:
   per Unit-Test deterministisch gesichert (realer Bau-Flow);
   die Live-Versuche bauten nichts, der Auswahl-Zustand (Toggle)
   machte den einzelnen Nachweis aber unscharf - ehrlich
   dokumentiert.
2. 287 Unit-Tests (3 neu: Sofort-Spawn mit Timer-Reset, Guard
   bei echter Welle (spawnNextWave setzt waveActive - nackte
   addAttatcher wuerden dem Guard entgehen, Test dokumentiert
   das), Zweitbau abgelehnt), 0 Fehler. Save-Roundtrip um den
   8. Typ erweitert (7 platzierbare + Riff), Bau-Menue-Angebot
   auf 7 Typen geprueft (4+3-Layout: Spalten auf 4, Breiten-
   Faktor des Layout-Tests 0,75 -> 0,60 justiert - der Langname
   "Anglerfisch-Leuchtfeuer" haette die konservative Schaetzung
   bei 1920 sonst faelschlich verletzt; realer Schnitt bleibt
   ~0,45-0,50).
3. Perf: Die 1.2.4-Anteile liegen NICHT im Frame-Pfad (Button-
   Text 2 Varianten gecacht, Panel-Button nur bei offener
   Auswahl, Platzierungs-Count nur bei aktivem Ghost, vgl.
   1.2.2-Disziplin). Messung weiterhin nur im degradierten
   Emulator moeglich (60 skia-Zeilen/s, Host-Neustart offen);
   0 FATAL / 0 ANR.
4. Version 1.2.4 (versionCode 18), gleicher Keystore, APK
   130.822 Bytes (1.2.3: 129.474; +1,3 KB durch Beacon-Sprite/
   Icon/Panel-Button).


---

# Version 1.2.5 – Szene-Hintergruende: Info, Optionen, Highscore (nach 1.2.4)

Die Vollbild-Szenen aus dem Hauptmenue (Info, Optionen, Highscore)
zeigen bislang nur den einfarbigen BG_BOTTOM-Grund - langweilig.
Jede Szene soll ein thematisches Hai-Motiv als Illustration
erhalten (programmatisch im M7-Sprite-Stil vorgerendert, keine
Asset-Dateien):
- INFO: ein Hai, der sich nachdenklich am Kinn kratzt.
- OPTIONEN: ein Hai, der mit einem Hammer hantiert (Werkstatt-
  Anmutung, passt zum Einstellungs-Charakter).
- HIGHSCORE: drei verschiedene Haiarten (Standardjaeger, Hammerhai,
  Weisser Hai) auf einem Sieger-Podest mit Plaetzen 1/2/3.

## Aufgaben 1.2.5

- [x] **I1 - Motiv-Renderer (programmatisch, M7-Stil):**
      Drei vorgerenderte Bitmaps (einmalig erzeugt, lazy im Render-
      Thread wie UiIcons; Fallback: heutiger BG_BOTTOM ohne Motiv,
      JVM-Tests unberuehrt): (a) Kinn-Kratzer: Hai-Silhouette mit
      angehobener Flosse am Kinn + nachdenklichem Blick-Punkt;
      (b) Hammer-Hai: Hai mit Hammer in der Flosse, Funken-/Span-
      Details; (c) Podest: drei Stufen (1/2/3), je Hai-Art eine
      Silhouette darauf, Medaillen-/Zahlen-Marker. Stil wie die
      bestehenden Sprites (Tiefsee-Palette, helle Umrisse gegen
      dunklen Grund).
- [x] **I2 - Einbau in die Szenen (Lesbarkeits-Sicherung):**
      Platzierung ohne Ueberlappung mit Buttons/Liste/Credits
      (Info/Optionen: Motiv in der freien Bildhaelfte oder unter
      dem Text, Highscore: unterhalb/um die Liste); Text bleibt
      lesbar (Umriss-Draw wie UICatalog). Motiv-Groesse weiten-
      relativ (max. ~40 % der Bildflaeche), auf 3 Formaten im Bild.
- [x] **I3 - Tests + Abnahme:**
      Pixel-Check je Szene: Motiv-Pixel sichtbar (Farb-Sampling
      gegen den alten Einheits-Grund), Buttons/Texte unveraendert
      lesbar, Klick-Flaechen unveraendert (Szenen-Logik bleibt).
      Suite gruen; Perf: ein Blit je Szene-Draw (vorgerendert),
      10-Min-Soak mit Szenen-Oeffnen im Fenster.

## Abnahme-Kriterium 1.2.5

**Fertig wenn:**
1. Alle drei Szenen zeigen ihr Motiv (Pixel-Check), kein Text/
   Button verdeckt, Interaktionen unveraendert (Back, Links,
   Sound-Toggle, Highscore-Zugang).
2. Layout auf 3 Formaten geprueft (UiLayoutTest um Motiv-Bereiche
   ergaenzt oder per Konstanten gesichert); Suite komplett gruen.
3. Perf ohne Regression (avg <= 0,7 ms im sauberen Emulator-Zustand
   - andernfalls Host-Neustart zuerst, vgl. 1.1.7), 0 FATAL/ANR.
4. Version 1.2.5 (versionCode 19), signiert, APK-Groesse
   dokumentiert.

## Aufwand 1.2.5
| Aufgabe | Aufwand |
|---------|---------|
| I1 (3 Motiv-Renderer)   | 1,5 |
| I2 (Szenen-Einbau)       | 0,5 |
| I3 + Tests + Abnahme     | 0,5 |

**Status: Abgenommen** (Release-Build 1.2.5, Emulator API 37):
1. Live per Pixel-Check in allen drei Szenen: INFO zeigt den Kinn-
   Kratzer-Hai (32 Sampler in Hai-Koerperfarbe rechts neben der
   Button-Spalte, dazu die "Gedanken-Punkte"), OPTIONEN den Hammer-
   Hai mit Funken (33 Sampler), HIGHSCORE das Sieger-Podest
   (264 Holz- + 18 Gold-Plaketten-Sampler, drei Hai-Silhouetten:
   Standardjaeger auf Platz 1, Hammerhai mit Kopf-Balken auf 2,
   heller Weisser Hai auf 3, Plaketten 1/2/3). Back-Buttons und
   alle Klickflaechen unveraendert (laufend im Abnahme-Ablauf
   genutzt).
2. 288 Unit-Tests (1 neu: sceneIllustrationsStayInBoundsAndClear-
   Buttons auf 3 Formaten - Motiv-Rechtecke im Bild und frei von
   Info-/Options-Buttons), 0 Fehler. Motiv-Bereiche als companion-
   Konstanten (InfoScene/OptionsScene/HighscoreScene.motifRect)
   fuer Tests und Pixel-Abnahmen.
3. Perf: identisches Muster wie 1.2.3-Pergament (lazy vorgerender-
   te Bitmap, EIN Blit je Szenen-Draw, keine Allokation im Frame)
   - dort bereits relativ gemessen als guenstiger als Weltbetrieb.
   Der Emulator bleibt degradiert (~60 skia-Zeilen/s, Host-Neustart
   noch offen), 0 FATAL / 0 ANR.
4. Version 1.2.5 (versionCode 19), gleicher Keystore, APK 132.254
   Bytes (1.2.4: 130.822; +1,4 KB durch drei Illustrationen +
   Motiv-Rect-Konstanten).
5. NACH-Review-Verdopplung (Grafik-Begutachtung des Spielers): Die
   Motive kamen zu klein rueber - Render-Aufloesung der Bitmaps
   verdoppelt (220/220/260 -> 440/440/520 px, Skalierungsfaktor
   s bleibt auf die Original-Bezugsmasse bezogen, damit das
   Motiv die groessere Bitmap ausfuellt statt nur zu wandern)
   und die motifRect-Anker umgestellt: Größe je Format
   height*0,62 (Info/Optionen) bzw. height*0,55 (Highscore),
   linker Rand am Button-Spalten-Rand verankert (statt fester
   0,72/0,74/0,80-Breite mit 340/300-px-Deckel). Live erneut
   verifiziert: INFO 255 Sampler (vorher 32, Blob 224x224 px),
   OPTIONEN 290 (vorher 33), HIGHSCORE-Podest 2294 (vorher 264,
   Blob 380x216 px) - je ~8-9x mehr Motiv-Pixel. 288 Tests
   weiter gruen (Layout-Test haelt mit den neuen Anker-Rects),
   APK 132.250 Bytes, Version bleibt 1.2.5 (versionCode 19 -
   Verfeinerung vor dem naechsten Release).

---

# Version 1.2.6 – Package-Refactoring: de.firsttestgame -> neuer Name (nach 1.2.5)

Der Package-Name (namespace + applicationId "de.firsttestgame") stammt
aus dem Projektgeruest und passt nicht mehr zum Namen. Umstellung auf
einen neuen, finalen Namen (z. B. "de.hoatzindevelopment.abyssempire"
- endgueltiger Name nach Absprache). BEWUSSTE Konsequenzen (vorab
dokumentiert): Die neue Application-ID ist eine NEUE App-Identitaet -
Bestehende Installationen behalten die alte App (kein Update-Pfad),
Spielspeicher und Highscores liegen je Application-ID in getrennten
Sandboxes und MIGRIEREN NICHT (technisch auf normalen Geraeten nicht
moeglich). Deshalb: VOR dem Play-Store-Release umsetzen - nach der
Veroeffentlichung ist die Store-Application-ID unveraenderlich, ein
spaeterer Umbau waere eine zweite App.

## Aufgaben 1.2.6

- [x] **PR1 - Mechanisches Refactoring:**
      app/build.gradle.kts: namespace + applicationId auf den neuen
      Namen. Verzeichnisbaeume app/src/main/java/de/firsttestgame und
      app/src/test/... umbenennen, 76 package-Deklarationen + 108
      Import-/FQN-Verweise anpassen (Skript/Refactoring). Manifest
      pruefen: activity android:name=".MainActivity" ist relativ und
      laeuft automatisch mit; Permissions/Provider-Referenzen gibt
      es keine. Der lokale Projektordner (D:\...\firsttestgame)
      und der GitHub-Repo-Name (abyss-empire) bleiben unberuehrt.
- [x] **PR2 - Vollregression unter neuer Identitaet:**
      Komplette Suite (280+ Tests) unter den neuen Packages, Release-
      Build (gleicher Keystore - Signatur aendert sich NICHT), Emulator:
      frische Installation unter neuer ID, alle Abnahmeflows (Intro,
      Menue, Highscore, Game-Over-Wege, Wellen) einmal gegen die neue
      ID; adb-Kommandos der Abnahme-Skripte auf die neue ID umstellen.
      Dokumentiert: Alte App bleibt auf Geraeten neben der neuen
      bestehen (manuelles Deinstallieren empfohlen), Speicher/High-
      scores starten frisch.
- [x] **PR3 - Aufraeumen + Bericht:**
      Pruefen: ProGuard/R8-Regeln (JSON-Save-Pfad), BuildConfig-Ver-
      weise, Log-Tags, evtl. verbliebene "firsttestgame"-Namen in
      Doku/Kommentaren (historische Roadmap-Texte bleiben unberuehrt).
      Roadmap-Status wie ueblich; kein Save-Format-Bump noetig (Save
      referenziert den Package nicht), aber Version dokumentiert den
      Identitaetswechsel.

## Abnahme-Kriterium 1.2.6

**Fertig wenn:**
1. Suite komplett gruen unter den neuen Packages; Release-Build mit
   gleichem Keystore; App startet im Emulator unter der neuen App-
   ID (Launcher: "Abyss Empire"), alle Kernflows einmal verifiziert.
2. Keine Referenz auf den alten Package-Namen im Produktionscode
   (grep leer); historische Roadmap-Abschnitte unberuehrt.
3. Folgen dokumentiert und bewusst akzeptiert: neue App-Identitaet,
   kein Update-Pfad von der alten Installation, Speicher/Highscores
   migrieren nicht.
4. Version 1.2.6 (versionCode 20), signiert, APK-Groesse dokumentiert.

## Aufwand 1.2.6
| Aufgabe | Aufwand |
|---------|---------|
| PR1 (Mechanik)        | 0,5 |
| PR2 (Vollregression)   | 0,5-1 |
| PR3 + Bericht          | 0,5 |

**Status: Abgenommen** (Release-Build 1.2.6, Emulator API 37):
1. PR1: namespace + applicationId auf "de.hoatzindevelopment.
   abyssempire", beide Verzeichnisbaeume (main + test) per git mv
   verschoben, 77 package-Deklarationen + 109 Import-/FQN-Verweise
   in einem Durchlauf umgeschrieben - Verbleib nach Grep: 0.
   Manifest laeuft automatisch mit (relative Activity-Angabe),
   ProGuard/R8-Regeln ohne Package-Bezug, keine Res-Referenzen.
   README-Projektstruktur-Pfad angepasst; historische Roadmap-
   Abschnitte bewusst unberuehrt.
2. PR2 Vollregression: 288 Unit-Tests unter den neuen Packages
   unveraendert gruen (kein Test brauchte Anpassung - reine
   Umbenennung). Release-Build mit gleichem Keystore (Signatur
   unveraendert), APK: package name 'de.hoatzindevelopment.
   abyssempire', versionCode 20, versionName 1.2.6, application-
   label 'Abyss Empire' (aapt-verifiziert). Live unter neuer ID:
   alte App (de.firsttestgame) deinstalliert, neue installiert,
   Intro/Menue/Weiterspielen, Bau-Menue auf/zu, Highscore-Szene
   mit frischem Speicher (Leerzustand + Podest-Motiv per Pixel-
   Check), Welle 1 spawnt - die dokumentierte Konsequenz zeigt
   sich live: Speicher/Highscores starten frisch (alte Daten
   unerreichbar, bewusst akzeptiert).
3. PR3: keine Rest-Referenzen im Produktionscode; Log-Tags
   (Game/GameView) unveraendert, BuildConfig-Verweise laufen
   mit. Perf-Soak 10,7 min auf FRISCH gebootetem Gast: avg 0,78
   ms (Vorfenster 0,83), maxWork 8,2 ms, overBudget 0 Fenster,
   0 FATAL / 0 ANR, PID konstant. Kontext ehrlich dokumentiert:
   Der Alt-Emulator der Session war gethrasht (servicemanager
   65 % CPU -> Messung avg 17 ms), ein Cold-Boot half dort
   NICHT mehr (skia-Flut ab erster Minute); erst der zweite
   frische Boot lieferte die o.g. brauchbaren Werte - der
   Host-Neustart bleibt fuer Referenz-Absolutwerte (0,57-0,63
   historisch sauber) empfohlen, die Budget-Disziplin
   (overBudget 0) ist aber bereits vollstaendig erfuellt.
4. Version 1.2.6 (versionCode 20), gleicher Keystore, APK
   132.294 Bytes (1.2.5: 132.250; +44 Bytes - nur Namen,
   kein Zuwachs an Logik).

---

# Version 1.2.7 – Karte: Karten-Bau anpassen und 10x10-Grid (nach 1.2.6)

Drei Karten-Verbesserungen: Die Karten-Bauleiste eroberter
Sektoren dupt (Handelsplatz/Anemone fallen weg, "Steinkoralle"
kommt dazu) und das Sektoren-Grid waechst von 3x3 auf 10x10 -
so gebaut, dass eine spaetere Vergroesserung den Spielstand
nicht bricht.

## Aufgaben 1.2.7

- [x] **K1 - Karten-Bauleiste anpassen:**
      MapScene.placeable: TRADING_POST und ANEMONE entfernen
      (bleiben im Welt-Bau-Menue; die Anemonen-je-Sektor-Regel
      bleibt fuer den Welt-Bau, der Karten-Bau von Anemonen/
      Handelsplatz entfaellt ganz). Buttons/Tests anpassen
      (5 -> 4 Typen).
- [x] **K2 - Neuer Gebaeudetyp "Steinkoralle":**
      Produziert Korallen (passiv wachsende Kolonie; Kosten/Rate
      in GameConfig, Balance unter dem Riff-Grundzuwachs - kleiner
      als das Riff, als Sektor-Ergaenzung). Karten-exklusiv
      (Welt-Bau unveraendert); Sprite + Icon im M7-Stil
      (verzweigte Steinkoralle); Save-Roundtrip, Produktionstests.
- [x] **K3 - Grid 10x10, speicherstand-kompatibel:**
      GRID_SIZE 3 -> 10. Der Save speichert Sektoren bereits mit
      x/y-Koordinaten als Liste - Alt-Saves (3x3) laden ins grosse
      Grid, neue Koordinaten entstehen als FOGGED. hitTest/
      Nachbarschafts-/isAttackable-Logik sind groessenunabhaengig,
      pruefen + testen (Eroberungskette ueber mehr Ringe,
      Anzeige/Panning der groesseren Karte). Erweiterbarkeit:
      GRID_SIZE bleibt die EINZIGE Konstante - ein spaeterer
      Sprung auf 12x12 usw. darf bestaehende Saves nicht brechen
      (Test: Alt-3x3-Save laedt ins 10x10-Grid, Spielstand/
      Welle/Gebaeude unveraendert).
- [x] **K4 - Tests + Abnahme:**
      Karten-Typen (4, ohne Handelsplatz/Anemone, mit Stein-
      koralle), Steinkorallen-Produktion + Roundtrip, 10x10-Grid-
      Logik (Nachbarschaft/Eroberung/Scrollen), Alt-Save-Migration.
      Live: Karte zeigt 100 Sektoren, Panning, Steinkorallen-Bau
      im eroberten Sektor, Perf-Soak.

## Abnahme-Kriterium 1.2.7

**Fertig wenn:**
1. Karten-Bauleiste bietet 4 Typen (ohne Handelsplatz/Anemone,
   mit Steinkoralle); Steinkoralle produziert Korallen im
   eroberten Sektor (Logcat/Persistenz).
2. 10x10-Grid live: Karte scrollt, Heimat + 99 Zonen, Eroberungs-
   kette funktioniert ueber mehrere Ringe; Alt-Save (3x3-Stand)
   laedt vollstaendig ins 10x10-Grid ohne Verlust (Kaltstart).
3. Suite gruen inkl. neuer Tests; Perf-Soak ohne Regression,
   0 FATAL/ANR.
4. Version 1.2.7 (versionCode 21), signiert, APK-Groesse
   dokumentiert.

## Aufwand 1.2.7
| Aufgabe | Aufwand |
|---------|---------|
| K1 (Bauleiste anpassen)   | 0,5 |
| K2 (Steinkoralle)          | 1   |
| K3 (10x10-Grid + Save)     | 1,5 |
| K4 + Tests + Abnahme       | 1   |

## Status 1.2.7 (fertig)

Umsetzung:
1. K1: MapScene.placeable auf 4 Typen (Fressgrund, Gilde, Spalte,
   Steinkoralle) - Handelsplatz/Anemone nur noch im Welt-Bau-Menue;
   die globalen Guards in Game.tryPlaceSectorBuilding bleiben als
   Schutz erhalten (Test setzt mapPlacementType direkt, Setter dafuer
   internal).
2. K2: BuildingType.STONE_CORAL + StoneCoral-Klasse (NewBuildings.kt,
   passiv, 1 Stufe) + Factory + Sprite (Fels-Sockel mit Korallen-
   Aesten) + UiIcons-Icon; GameConfig: Radius 40, Kosten 50 Korallen,
   Produktion 0,4 Korallen/s (unter dem Riff-Grundzuwachs 1,0/s),
   Roundtrip im Save (Name-Lookup).
3. K3: GRID_SIZE 10, HOME_X/HOME_Y = GRID_SIZE/2 (oefentlich, einzige
   Konstante fuer kuenftige Vergroesserungen); fromJson leitet jeden
   HOME-Eintrag (auch Alt-3x3 mit Heimat 1/1) auf den aktuellen
   Heimatsektor um - Gebaeude landen in der geteilten Welt-Liste;
   MapScene startet auf den Heimatsektor zentriert (Offsets geklemmt),
   Panning ueber die 4000px-Karte, Pixel-Offsets fuer Tests lesbar.
4. K4: 294 Tests (6 neu: Grid-Groesse/Erweiterbarkeit, Home-Zentrierung,
   Panning-Klemmen, Steinkorallen-Produktion + Karten-Bau/Persistenz,
   Alt-3x3-Home-Migration), 0 Fehler.

Live-Abnahme (frisch gebooteter Emulator, 2400x1080):
1. Karte: Heimat-Tile pixelgenau zentriert (Flossen-Marker + Ink-
   Rahmen bei 1000..1400/340..740), Nachbar (5,4) ALPHA, Ring-2
   FOGGED (Nebel-Blobs), Eroberung von (5,4) live durchgefochten
   ("Sektor (5,4) erobert"), Panning mit 22.929 geaenderten Samplern.
2. Steinkoralle: 4. Karten-Button -> "Gebaeude in Sektor (5,4)
   gebaut: Steinkoralle", eroberter Sektor zeigt EROBERT + 1 Gebaeude
   (538 Ink-Sampler), Affordable-Zustaende der 4 Buttons korrekt
   (Fressgrund/Gelde gruen, Spalte/Steinkoralle nach Bau zu teuer),
   Kaltstart erhaelt Sektor + Gebaeude vollstaendig.
3. Perf-Soak ~10 min (Karte mit Panning + Welt): 99 Messfenster,
   avg 0,71 ms, maxWork ~4,4 ms, overBudget 0 ueberall, 0 App-FATAL/
   ANR (einzig der UWB-Vendor-Dienst des Emulators stuerzte ab,
   App unberuehrt). Werte im sauberen Bereich (historisch 0,57-0,78).
4. Version 1.2.7 (versionCode 21), gleicher Keystore, APK
   132.818 Bytes (1.2.6: 132.294; +524 Bytes - Typ, Klasse, Renderer).

Grenzen (ehrlich): Steinkorallen-Produktion live nur per Unit-Test
genau gesichert (0,4/s; HUD-Ziffern nicht per Pixel lesbar); Alt-Save-
Migration als Unit-Test (Release-Build nicht debuggable, kein
Fabricate-Old-Save auf Geraet); erste Eroberungs-Runde ging gegen den
Alt-Spielstand (Welle 3 + Riesenkrake) verloren - nach frischem
Reset reproduzierbar sauber.

---

# Version 1.2.8 – Ressourcen-Produktion im Bau-Menue + Handel x10 (nach 1.2.7)

## Aufgaben 1.2.8

- [x] **R1 - Produktion je Sekunde in den Bau-Buttons:**
      Welt-Bau-Menue UND Karten-Bauleiste: rechts im Button die
      "Erzeugten Ressourcen in Sekunden" anzeigen (z. B.
      "+1 Kor/s", passive Gebaeude: "-"), damit erkennbar ist, was
      ein Gebaeude produziert. Texte als Konfig-Konstante einmalig
      gecacht (M5.75); Breite im Layout-Test sichern (Button-Layout
      1.1.4: rechts Platz fuer Kurzform, ggf. zweite Zeile).
- [x] **R2 - Handelsplatz x10-Tausch:**
      Je Tausch-Route ein zusaetzlicher x10-Button RECHTS neben dem
      bestehenden (gleiche Route, 10-fache Menge geben/nehmen);
      Layout: Route-Zeile mit [Route-Text][x1][x10]. Verlust-
      behaftung bleibt proportional (10x Route = 10x Verlust);
      Panel-Hoehe fuer breitere Zeilen pruefen (TRADE_PANEL_RAISE-
      Disziplin 1.1.3).
- [x] **R3 - Tests + Abnahme:**
      x10-Route: Abzug/Gutschrift exakt 10x, Ablehnung ohne Rest-
      Bestand, alle 4 Routen; Produktions-Texte gegen Konzept-
      Tabelle; Layout-Test (x10-Buttons im Bild, keine Panel-
      Kollision); Live-Abnahme + Perf-Soak.

## Abnahme-Kriterium 1.2.8

**Fertig wenn:**
1. Bau-Buttons zeigen ihre Produktion je Sekunde (Pixel-Check,
   2 Menues), Werte stimmen mit GameConfig ueberein.
2. x10-Tausch an allen 4 Routen live verifiziert (Logcat-Ressourcen-
   stand vor/nach), Verlust 10x proportional per Test.
3. Suite gruen, Layout auf 3 Formaten, Perf-Soak ohne Regression.
4. Version 1.2.8 (versionCode 22), signiert, APK-Groesse
   dokumentiert.

## Aufwand 1.2.8
| Aufgabe | Aufwand |
|---------|---------|
| R1 (Produktions-Anzeige)   | 1   |
| R2 (x10-Handel)             | 0,5-1 |
| R3 + Tests + Abnahme        | 0,5 |

## Status 1.2.8 (fertig)

Umsetzung:
1. R1: GameConfig.producedPerSecond(type) liefert die St.-1-Rate
   (Fressgrund 1 Bio/s, Gilde 0,5 Kalk/s, Spalte 0,4 Lum/s, Stein-
   koralle 0,4 Kor/s; passive Typen null); BuildMenu.productionShort-
   Text formatiert "+1 Bio/s" (Ganzzahl/1 Dezimal) bzw. "-" fuer
   passive. Welt-Bau-Menue: 3-Zeilen-Layout im 88-px-Button (Name
   20f@32, Kosten 16f@56, Produktion 16f@80 rechtsbuendig, Baselines
   gestaucht - Produktion in eigener Zeile statt ueberlappter Kosten-
   zeile); Karten-Bauleiste: Produktion rechtsbuendig neben den
   Kosten (22f). Beide Text-Caches einmalig je Typ (M5.75).
2. R2: tradeX10Buttons je Route (150 px breit, rechts neben den x1-
   Buttons, gleiche Zeilen/Panelgeometrie - Panel-Hoehe/TRADE_PANEL_
   RAISE unveraendert); executeTrade(route, factor) mit Resource-
   Inventory.times(factor) - Verlust bleibt exakt proportional;
   Route-Text zentriert im x1-Button, "x10"-Label im x10-Button,
   Affordability je Faktor geprueft; Log unterscheidet "Tausch x10".
3. R3: 300 Tests (6 neu): x10 exakt 10x, x10-Ablehnung ohne Teil-
   bestand, alle Routen proportional verlustbehaftet bei x10, Raten
   gegen Konzept-Tabelle, Produktions-Text-Format, x10-Layout auf
   3 Formaten (im Bild, rechts von x1, ausserhalb Bau-Menue-Band).

Live-Abnahme (Emulator, 2400x1080):
1. Produktions-Anzeige: Welt-Bau-Menue - Text-Cluster im Rechts-
   bereich der Produktionszeile bei Fressgrund/Gilde/Spalte (56-281
   Sampler), "-"-Strich bei Kaserne/Leuchtfeuer (7 Pixel, maxR
   131); Karten-Bauleiste - alle 4 Buttons zeigen Produktionstexte
   (88-133 Sampler). Werte per Unit-Test gegen GameConfig gesichert.
2. x10-Handel live: Route 2 "Tausch x10: 80 Bio -> 40 Kor" (09:11:54)
   und Route 1 "Tausch x10: 100 Kor -> 50 Kalk" (09:14:07) im Logcat,
   exakte 10-fache Betraege; x10-Button per Pixelmessung lokalisiert
   (blau iff leistbar, 150 px breit). Routen 3/4 live nicht bestand-
   deckbar (Wrk 0/Kalk knapp) - Ablehnung und Proportionalitaet per
   Unit-Test gesichert.
3. Perf-Soak ~8,5 min (Welt + Bau-Menue + Karte/Panning + Handels-
   panel): 81 Fenster, avg 0,79 ms, max 1,68 ms, 80/81 overBudget=0
   (1 Fenster mit 3 Frames ueber Budget bei Game-Over-Uebergang,
   maxWork 56 ms), 0 App-FATAL/ANR.
4. Version 1.2.8 (versionCode 22), gleicher Keystore, APK
   133.742 Bytes (1.2.7: 132.818; +924 Bytes).

Grenzen (ehrlich): Wellen-Verteidigung per adb-Taps blieb unzuver-
laessig (Spiel-Hai erreicht stehende Angreifer am Riff-Rand nur bei
exakter Position; Sonden teilweise auf schwebende rote Texte ge-
raten) - Abnahme-Runden liefen deshalb bewusst im 90-s-Fenster
zwischen Wellen bzw. ueber Weiterspielen (Produktion laeuft weiter);
Routen 3/4-x10 nur per Unit-Test.

---

# Version 1.2.9 – Kleine Verbesserungen (nach 1.2.8)

## Aufgaben 1.2.9

- [x] **S1 - Instinkt-Spalten-Ueberschriften lesbar:**
      InstinctScene: die Ueberschriften der beiden Spalten
      ("Instinkte" und "Mutationen") sind nicht lesbar (Farbe/
      Position gegen den Hintergrund pruefen, UICatalog-Outline/
      Kontrast anwenden, ggf. Position anpassen).
- [x] **S2 - Ambiente-Loop verlaengern:**
      Der 8-s-Pad-Loop wirkt wie ein Stutter. WavGenerator-Loop auf
      30-60 s verlaengern (mehr Variation im Pad, sanftes Loop-Fade
      an den Raendern), ggf. Loopen ueber 2 versetzte Segmente.
      Achtung Speicher: laengerer Loop = groessere WAV im cacheDir -
      Groesse dokumentieren.
- [x] **S3 - App-Logo "Abyss Empire":**
      Launcher-Icon passend zum Namen: programmatisch erzeugtes
      Icon (Hai-Silhouette/Tiefsee-Anmutung) als Adaptive Icon
      (foreground + background layer, alle Dichten); ic_launcher
      in den Res-Ordnern ersetzen, Rundungs-/Scale-Verhalten am
      Emulator pruefen.
- [x] **S4 - Tests + Abnahme:**
      Ueberschriften-Pixel-Check (lesbar), Loop-Laenge im Sound-
      Engine-Log, Icon auf dem Launcher sichtbar (uiautomator/
      Screenshot). Suite gruen, Perf-Soak (Ambiente-Speicher!),
      APK-Groesse dokumentiert.

## Abnahme-Kriterium 1.2.9

**Fertig wenn:**
1. Beide Spalten-Ueberschriften der Instinkt-Szene lesbar (Pixel-
   Check gegen vorher).
2. Ambiente-Loop >30 s ohne wahrnehmbaren Stutter (Laenge im Log),
   Speicher-Auswirkung dokumentiert.
3. Neues Launcher-Icon sichtbar (Launcher-Ansicht), alle Dichten
   erzeugt.
4. Suite gruen, Perf-Soak ohne Regression. Version 1.2.9
   (versionCode 23), signiert, APK-Groesse dokumentiert.

## Aufwand 1.2.9
| Aufgabe | Aufwand |
|---------|---------|
| S1 (Ueberschriften)     | 0,5 |
| S2 (Ambiente-Loop)      | 1   |
| S3 (App-Logo)           | 1   |
| S4 + Tests + Abnahme    | 0,5 |

## Status 1.2.9 (fertig)

Umsetzung:
1. S1: Ursache gefunden - die Spalten-Titel standen fix bei y=190,
   die erste Button-Zeile begann aber schon bei rowsTop ~184: Die
   Buttons wurden NACH den Titeln gezeichnet und haben sie komplett
   ueberdeckt. Fix: rowsTop mindestens 200, Titel-Baseline
   rowsTop-24 (neu InstinctScene.columnTitleBaseline), volle
   Textfarbe (TEXT statt MUTED) und 26f.
2. S2: WavGenerator.ambientLoop 8 s -> 45 s: drei Pad-Akkorde
   (Am/F/G, je 15 s) mit Raised-Cosine-Blenden, Sub-Bass A1,
   langsames Lautstaerke-Schweben je Pad; nahtloser Loop per
   2-s-Kopf-Ende-Crossfade (letztes Sample = direkte Fortsetzung
   des ersten). SoundEngine loggt Laenge + cacheDir-Groesse.
3. S3: Adaptive Icon (mipmap-anydpi-v26: Tiefsee-Hintergrund
   #10333A + Hai-Silhouette-Vordergrund im Safe-Zone-Viewport 108),
   Legacy-Vektor fuer API 24/25 in mipmap/, Manifest auf
   @mipmap/ic_launcher, altes blaues Dreieck entfernt.
4. S4: 303 Tests (4 neu/ersetzt): Spalten-Titel ueber den Buttons
   auf 3 Formaten, Loop 45 s + dokumentierte Groesse, nahtloser
   Wrap (Naht-Sprung < 2500), Akkord-Variations-Nachweis per
   Goertzel (Grundton-Dominanz je Segment).

Live-Abnahme (Emulator, 2400x1080):
1. Instinkt-Szene: beide Spalten-Titel als weisse Outlined-Texte
   lesbar (118/168 helle Sampler bei Baseline 176), erste Button-
   Zeile ab y=200 - keine Ueberzeichnung mehr.
2. Ambiente-Loop: "Ambient-Loop: 45 s, 1984544 Bytes im cacheDir"
   im SoundEngine-Log; WAV-Generierung weiterhin nicht blockierend
   (527 ms im Hintergrund-Thread); cacheDir-Footprint ~1,89 MB
   (vorher ~0,35 MB) - dokumentiert und unkritisch.
3. Launcher-Icon: im App-Drawer sichtbar (1045 Hintergrund-Pixel
   #10333A, 514 weisse Hai-Pixel im Icon-Umfeld), Launcher maskiert
   adaptive Laender wie vorgesehen.
4. Perf-Soak ~9 min (Welt + Instinkt-Szene + Karte): 107 Fenster,
   avg 0,75 ms, 106/107 overBudget=0 (1 Fenster 4 Frames ueber
   Budget bei Wellen-/Game-Over-Uebergang, max 19,7 ms), 0 App-
   FATAL/ANR.
5. Version 1.2.9 (versionCode 23), gleicher Keystore, APK
   135.778 Bytes (1.2.8: 133.742; +2.036 Bytes).

Grenzen (ehrlich): Stutter-Freiheit per Ohr nicht pruefbar (adb),
per Konstruk gesichert (45 s Loop, nahtloser Crossfade, Unit-Tests
zur Naht); Icon auf einem Launcher (Pixel-Launcher, Zirkelmaske)
geprueft - andere Masken/Formate analog per Adaptive-Icon-Standard.

---

# Version 1.2.10 – Options-Menue: Sound-Modi + Schwierigkeit (nach 1.2.9)

## Aufgaben 1.2.10

- [x] **O1 - Sound-Abschaltungen granular:**
      Statt einem Sound-Toggle drei Abschalt-Stufen: (a) ganzer
      Sound aus, (b) nur Hintergrundmusik aus (Effekte bleiben),
      (c) nur die anderen Geraeusche aus (Musik bleibt). Umsetzung:
      SoundSetting-Enum statt Boolean, SoundEngine-Toggles fuer
      Musik + Effekte getrennt, Options-Szene mit drei Buttons/
      Zustandsanzeige, Persistenz im Save (tolerant laden wie
      soundEnabled), Pause-Overlay-Schalter konsistent halten.
- [x] **O2 - Schwierigkeitsregulator (3 Stufen):**
      Regulator, wie schnell die Wellen schwerer werden (z. B.
      Leicht: Wachstum halbiert, Normal: heutige Werte, Schwer:
      Wachstum erhoeht). GameConfig-Skalierungsfaktor je Stufe
      (multiplikativ auf die Growth-Konstanten, Basiswerte
      unangetastet), Persistenz im Save (tolerant, Default Normal),
      Options-UI mit 3er-Auswahl, Highscore-Fairness dokumentieren
      (Eintraege ab 1.2.10 gemischt oder Schwierigkeits-Feld -
      Entscheidung bei Umsetzung).
- [x] **O3 - Tests + Abnahme:**
      Sound-Stufen (Engine-Toggle je Stufe, Persistenz-Roundtrip,
      Szenen-Zugang), Schwierigkeits-Skalierung gegen Konzept-
      Tabelle (HP/DPS/Anzahl je Welle je Stufe), Alt-Save-
      Toleranz, Live-Abnahme beider Regler + Perf-Soak.

## Abnahme-Kriterium 1.2.10

**Fertig wenn:**
1. Drei Sound-Abschalt-Stufen live wirksam (Musik/Effekte je
   Stufe im Logcat/Verhalten), Persistenz ueber Kaltstart.
2. Schwierigkeitsregulator: Wellen-Skalierung je Stufe per Test
   gegen die Tabelle, live sichtbarer Unterschied (Wellen-HP im
   Log bei 2 Stufen), Persistenz ueber Kaltstart.
3. Suite gruen, Perf-Soak ohne Regression. Version 1.2.10
   (versionCode 24), signiert, APK-Groesse dokumentiert.

## Aufwand 1.2.10
| Aufgabe | Aufwand |
|---------|---------|
| O1 (Sound-Stufen)      | 1   |
| O2 (Schwierigkeit)       | 1   |
| O3 + Tests + Abnahme    | 1   |

## Status 1.2.10 (fertig)

Umsetzung:
1. O1: SoundMode-Enum (ALL_ON/MUSIC_OFF/EFFECTS_OFF/ALL_OFF) ersetzt
   das Boolean; Game.sound() prueft effectsEnabled VOR dem Engine-
   Aufruf (Konstruktor-Parameter heisst jetzt playSound). SoundEngine
   mit getrennten Toggles setMusicEnabled/setEffectsEnabled (Musik
   pausiert/resumet, Effekte schweigen still). Options-Button und
   Pause-Overlay tippen beide durch den 4er-Zyklus (Konsistenz).
   Persistenz Save v9 ("soundMode"); v8-Boolean soundEnabled wird
   tolerant migriert (false -> ALL_OFF).
2. O2: DifficultyMode-Enum (EASY 0,5 / NORMAL 1,0 / HARD 1,5) -
   growthFactor wirkt multiplikativ auf WAVE_HP_GROWTH_PER_WAVE und
   WAVE_DPS_GROWTH_PER_WAVE in waveHp/waveDps; Basiswerte, Panzerung
   und Angreifer-Anzahl unberuehrt. Options-Szene: 3 Buttons nebenein-
   ander (kompakte Breite, passt auf 1080er), selektierte Stufe teal.
   Persistenz Save v9 ("difficulty", Default NORMAL). Highscore-
   Fairness: Eintraege bleiben GEMISCHT (bewusst keine Trennung -
   leichte Stufen erlaeben laengere Laeufe, dokumentierte Entscheidung;
   ein Schwierigkeits-Feld pro Eintrag waere ein Formatwechsel und
   bleibt optionaler Folgeschritt).
3. O3: 306 Tests (netto +3): Modus-Zyklus + Persistenz (Optionen UND
   Pause), Effekte still bei EFFECTS_OFF (injizierte playSound-
   Lambda zaehlt), Wellen-Skalierung gegen Konzept-Tabelle (Welle-2-
   HP/DPS je Stufe), Alt-Save-v8-Boolean-Migration, Schwierigkeits-
   Persistenz + Szenen-Zugang.

Live-Abnahme (Emulator, 2400x1080):
1. Sound-Zyklus live: "Sound-Modus: MUSIK AUS" -> "EFFEKTE AUS" ->
   "AUS" -> "AN" im Logcat; Kaltstart erhaelt den Modus.
2. Schwierigkeit: "Schwierigkeit: Schwer" im Logcat, SCHWER-Button
   pixelverifiziert teal (19,92,88) gegen blaue unselektierte Stufen
   (41,53,81), Auswahl nach Kaltstart unveraendert. Welle 1 spawnt
   in SCHWER normal (HP 20 - Welle 1 hat kein Wachstum); die
   Stufen-Differenz ab Welle 2 (24,5 vs 23,0 HP) ist unit-getestet.
3. Perf-Soak ~6 min (Welt + Instinkte + Game-Over-Zyklen): 74
   Fenster, avg 0,76 ms, 73/74 overBudget=0 (1 Uebergangsfenster),
   0 App-FATAL/ANR.
4. Version 1.2.10 (versionCode 24), gleicher Keystore, APK
   137.078 Bytes (1.2.9: 135.778; +1.300 Bytes).

Grenzen (ehrlich): Der Stufen-Unterschied der Wellen-HP ist live nur
bis Welle 2 sichtbar (Welle 1 wachstumsfrei) - eine unverteidigte
Abnahme-Runde erreicht Welle 2 nicht, daher Unit-Test als Primaer-
nachweis; Musik-Pause/Resume bei Moduswechsel am Geraet nicht per
adb hoerbar (Verhalten per Engine-Code + Tests gesichert).

---

# Version 1.2.11 – Package-Struktur-Analyse (nach 1.2.10)

## Aufgaben 1.2.11

- [x] **P1 - Analyse (Empfehlung + Begruendung):**
      Ist-Zustand dokumentieren (game/ haelt ~40 Klassen: Kern-
      logik, Entities, Szenen, UI-Katalog, Konfiguration).
      Pruefen, ob Aufteilungen die Wartbarkeit fuer Dritte
      erhoehen, z. B. entities/ (Building-Unterklassen, Attacker,
      Player, Fish), scenes/ (MapScene, InstinctScene, Info/
      Options/Highscore), core/ (Game, GameConfig, GameState,
      Vector2, InputController), ui/ (UICatalog, UiIcons,
      Illustrations) - oder ob die flache Struktur + klare Namen
      klein genug bleibt. Kriterien: Abhaengigkeitsrichtung
      (ui -> core, nie umgekehrt), Test-Zugriffe, Umbau-Aufwand
      vs. Nutzen. Empfehlung mit Begruendung festhalten; nur bei
      klarem Nutzen umsetzen.
- [x] **P2 - Ggf. Umsetzung:**
      Bei klarer Empfehlung: git-mv-Umbau (wie 1.2.6), Package-
      Deklarationen/Imports anpassen, Suite/Build/Abnahme (Voll-
      regression im Stil von 1.2.6/PR2). Ohne klaren Nutzen:
      bewusst nicht umsetzen und die Analyse als Ergebnis
      dokumentieren (vgl. 1.2.1/N3-Muster).

## Abnahme-Kriterium 1.2.11

**Fertig wenn:**
1. Analyse mit Empfehlung und Begruendung in der Roadmap
   dokumentiert (Entscheidung: umsetzen oder bewusst lassen).
2. Bei Umsetzung: Suite gruen unter neuer Struktur, Vollregression,
   Version 1.2.11 (versionCode 25), signiert; sonst Analyse-only-
   Commit ohne versionCode.

## Aufwand 1.2.11
| Aufgabe | Aufwand |
|---------|---------|
| P1 (Analyse)          | 0,5-1 |
| P2 (Umsetzung/Report)  | 0,5-1 |

## Status 1.2.11 (fertig - Analyse, bewusst OHNE Umsetzung)

Ist-Zustand (vermessen):
- app/src/main/java/.../abyssempire: 4 Packages (audio/ 2 Dateien,
  game/ 47 Dateien mit 7.756 Zeilen, persistence/ 1, ui/ 1 +
  MainActivity). Abhaengigkeitsrichtung auf Package-Ebene bereits
  sauber: ui -> game -> (audio, persistence); game kennt keines
  der anderen als Rueckreferenz.
- game/ im Detail: nur 2 Dateien ueber 500 Zeilen (Game.kt 2.687 =
  35 % des Packages, Sprites.kt 678); alle weiteren 45 Dateien
  < 430 Zeilen mit selbsterklaerenden Domain-Namen. 19 Dateien
  referenzieren GameConfig ohne Import (Same-Package), 8 nutzen
  UICatalog. 12 internal-Member - ALLE in Game.kt - werden von
  den 26 Test-Dateien im selben Package genutzt (Layout-Tests,
  interne Listen wie _buildings, mapPlacementType-Setter).
- Szenen sind bereits entkoppelt gezeichnet: MapScene/InstinctScene/
  OptionsScene nehmen Zustand als Parameter (kein Game-Verweis) -
  eine core/scenes-Schichtung waere moeglich, erzwingt aber nichts,
  was heute kaputt ist.

Kriterien-Pruefung gegen die Roadmap-Vorgabe:
1. Abhaengigkeitsrichtung: Auf Package-Ebene erfuellt; eine Sub-
   Struktur (entities/scenes/core/ui) wuerde die Richtung nur
   erneut per Konvention erzwingen - Game als Orchestrator
   referenziert zwingend Szenen UND Rendering (drawBuildingPanel,
   Ghosts), eine strikte core->ui-freie Schichtung ist mit dem
   aktuellen Game-Design nicht ohne Tiefenrefactoring erreichbar.
2. Test-Zugriffe: 26 Test-Dateien im game-Package greifen auf 12
   internal-Member in Game zu. Jeder Sub-Package-Umbau erzwinge
   entweder Mit-Umzug der Tests oder Sichtbarkeitsaufweichung
   (internal -> public) - beides Rueckregressionsrisiko ohne
   funktionalen Nutzen.
3. Umbau-Aufwand vs. Nutzen: ~47 Package-Deklarationen + Import-
   Churn in nahezu allen Dateien (heute importfrei durch Same-
   Package) - der wahre Wartbarkeitshebel ist NICHT die flache
   Struktur, sondern Game.kt mit 2.687 Zeilen (35 %). Ein Sub-
   Package-Split loest Game.kt nicht ab.

Empfehlung: BEWUSST NICHT umsetzen. Begruendung: Die flache
Struktur ist bei 45 schlanken, klar benannten Dateien kein
Naviationsproblem; der Split wuerde Aufwand und Risiko (Import-
Churn, Test-Mit-Umzug, internal-Aufweichung) kurz vor der Play-
Store-Vorbereitung (1.2.13) ohne adressierbaren Gewinn bringen.
Der relevante Folgeschritt waere stattdessen eine Zerlegung von
Game.kt (z. B. update/draw/save/wave-Module) als EIGENE Version
mit eigenem Regressionsschritt - bewusst NICHT in dieser Analyse-
Version versteckt. Sprites.kt (678) ist tolerierbar (reine
Renderer-Methoden ohne Logikverzahnung).

Abnahme: Analyse-Commit ohne versionCode/Build (Muster
1.2.1/N3): keine Code-Aenderung, Working Tree blieb unberuehrt,
306 Tests unveraendert gruen (Stand 1.2.10). Version 1.2.11 als
Dokumentations-Meilenstein; der naechste Code-Build (1.2.12 bei
Code-Aenderung bzw. 1.2.13) nimmt versionCode 25.

---

# Version 1.2.12 – Performance- & Testabdeckungs-Analyse (nach 1.2.11)

Analyse des 1.2.7-1.2.10-Stands (10x10-Karte, Produktions-Texte,
x10-Handel, Sound-Modi, Schwierigkeits-Skalierung) nach dem Vorbild
1.1.3/1.2.1: Messbasis, Luecken schliessen, nur bei messbarem
Gewinn optimieren.

## Aufgaben 1.2.12

- [x] **A1 - Performance-Analyse:**
      Pruefpunkte: 10x10-Karten-Draw (100 Tusche-Rahmen + Marker je
      Frame - Pergament bleibt 1 Blit, aber die Rahmen-Menge x10;
      ggf. Gesamtkarte vorrendern und als 1 Bild bewegen),
      Produktions-Texte (gecacht - Verifikation), x10-Handel
      (Event-Pfad), Sound-Modi (kein Frame-Pfad), Schwierigkeits-
      Faktor (nur Wellen-Spawn), Loop-Speicher (30-60 s WAV im
      cacheDir). 10-Min-Soak mit offener Karte als Basis; nur bei
      messbarem Gewinn umsetzen, sonst "kein Handlungsbedarf"
      dokumentieren.
- [x] **A2 - Testabdeckungs-Analyse:**
      Systematische Luecken-Pruefung der 1.2.7-1.2.10-Features:
      Karten-Bauleiste (4 Typen, Alt-Pfade), Steinkoralle
      (Produktion/Save/Platzierung), 10x10-Grenzen (Rand-Sektoren,
      Eroberung bis Map-Rand, Alt-Save-Migration), x10-Routen-
      Randfaelle, Sound-Stufen-Persistenz, Schwierigkeits-
      Invarianten (monoton, Default Normal). Ergaenzungen nur fuer
      echte Luecken.
- [x] **A3 - Bericht + ggf. Umsetzung:**
      Ergebnis in der Roadmap dokumentieren; bei Code-Aenderung:
      Soak + signierter Build (Version 1.2.12, versionCode 26);
      bei reinen Test-Ergaenzungen nur Test-Commit.

## Abnahme-Kriterium 1.2.12

**Fertig wenn:**
1. Analyse mit Messwerten und Code-Befunden je Pruefpunkt
   dokumentiert (optimiert / kein Handlungsbedarf mit
   Begruendung).
2. Gefundene Testluecken geschlossen, Suite komplett gruen,
   dokumentiert (welche neu, warum; oder explizit: keine Luecke).
3. Bei Code-Aenderung: 10-Min-Soak ohne Regression + signierter
   Build; sonst Test-Commit.

## Aufwand 1.2.12
| Aufgabe | Aufwand |
|---------|---------|
| A1 (Performance-Analyse) | 0,5-1 |
| A2 (Testabdeckung)      | 0,5-1 |
| A3 (Bericht/Umsetzung)  | 0,5 |

## Status 1.2.12 (fertig - Analyse + Test-Ergaenzungen)

A1 - Performance (alles kein Handlungsbedarf):
1. 10x10-Karten-Draw (Kernbefund): Dedizierter Vergleichs-Soak auf
   dem Emulator - Karte offen mit Panning: 32 Messfenster, avg
   0,69 ms, overBudget 0; Weltbetrieb direkt danach: 31 Fenster,
   avg 0,65 ms, overBudget 0. Die 100 Tusche-Rahmen + Marker kosten
   +0,04 ms (~6 % relativ) gegenueber der Welt - weit vom 16,7-ms-
   Budget entfernt. Vorrendern der Gesamtkarte wurde NICHT umge-
   setzt: 4000x4000 ARGB = 64 MB Bitmap gegen 0,04 ms Gewinn waere
   ein klarer Speicher-Verlust (Pergament-Blit bleibt wie ist).
2. Produktions-Texte: verifiziert - BuildMenu.costTexts/production-
   Texts und MapScene.buildCostTexts/buildProductionTexts sind
   getOrPut-Caches (einmalig je Typ, M5.75), kein String-Bau je
   Frame.
3. x10-Handel: reiner Tap-/Event-Pfad (executeTrade), Sound-Modi:
   Flag-Pruefung nur beim Event (play/startMusic), Schwierigkeit:
   growthFactor nur in waveHp/waveDps beim Wellen-Spawn - keiner
   der drei hat Frame-Pfad-Anteile.
4. Loop-Speicher: 45-s-WAV = 1.984.544 Bytes einmalig im cacheDir
   (Generierung 527 ms im Hintergrund-Thread), MediaPlayer
   streamt von Datei - kein Frame-/Speicherdruck im Spielbetrieb.

A2 - Testabdeckung (3 echte Luecken geschlossen, 309 Tests gruen):
1. allX10RoutesExecuteExactTenfoldAmounts (NewBuildingsTest): Alle
   4 Routen liefen nur als Wert-Vergleich - jetzt durchlaeuft jede
   Route den echten Panel-Pfad mit exakten 10x-Deltas.
2. difficultyGrowthIsMonotonicAcrossLevels (UiUsabilityTest): EASY
   war in keinem Test gesetzt - jetzt HP/DPS streng monoton ueber
   alle 3 Stufen (Welle 2) und Welle 1 unskaliert (Invariant:
   Basiswerte unangetastet).
3. mapHitTestOutsideGridReturnsNullAndCornersResolve (SectorGame-
   Test): 10x10-Grenzen des Hit-Tests - jenseits des Karteninhalts
   null, oberhalb links/oben Klemmung auf Kachel 0 (Dokumentation
   des Truncation-Verhaltens), Ecke (9,9) exakt. Ueberraschungs-
   befund beim Schreiben: Negative Screen-Koordinaten landen durch
   Truncation IMMER in Kachel 0 - unkritisch, da Panning klemmt
   und die UI nie dorthin gelangt.
Keine weiteren Luecken: Steinkoralle (Produktion/Save/Platzierung),
Alt-Save-Migration, Karten-Bauleiste (4 Typen + Handelsplatz-Guard-
Alt-Pfad), Sound-Modus-Persistenz (Optionen + Pause + Kaltstart) und
Schwierigkeits-Default waren bereits abgedeckt.

A3 - Bericht: Test-only-Commit (Muster 1.2.1/N3) - KEIN versionCode-
Build, versionCode bleibt 24 (naechster Code-Build nimmt 25).
309 Tests (3 neu), 0 Fehler; 0 FATAL/ANR im Soak. Keine Optimierung
umgesetzt: kein Pruefpunkt hatte messbaren Gewinn im Budget-Bereich.

---

# Version 1.2.13-a – Play-Store-Vorbereitung: Assets & Texte (nach 1.2.12)

Sammel-Version fuer alles, was die Store-Veroeffentlichung braucht
(der seit M7 bewusst offene Punkt): Ordnerstruktur, Screenshots,
Beschreibungen und ein simpler Trailer.

## Aufgaben 1.2.13-a

- [x] **ST1 - BESCHREIBUNG.md aktualisieren:**
      Stand aktualisieren: 1.2.13-Features (10x10-Karte, Stein-
      koralle, x10-Handel, Sound-Modi, Schwierigkeit), Links
      pruefen.
- [x] **ST2 - Store-Asset-Ordner:**
      Neuer Ordner "store/" fuer ALLE Play-Store-Materialien:
      Screenshots, Trailer, Kurzbeschreibung, Store-Texte,
      Grafiken (mit README, das den Stand dokumentiert). Nicht im
      APK-Build-Pfad.
- [x] **ST3 - Play-Store-Screenshots:**
      Emulator-Screenshots in Store-typischen Formaten (Telefon
      16:9 bzw. 9:16, ggf. Tablet) der Kernszenen: Welt mit HUD +
      Welle, Bau-Menue, Seekarte (10x10), Instinkte, Highscore,
      Game-Over. Mindestens 4 Screenshots; in store/screenshots/
      ablegen.
- [x] **ST4 - KURZBESCHREIBUNG.md:**
      Store-Kurzbeschreibung (Haupthinweis ~80 Zeichen + ggf.
      425-Zeichen-Volltext) fuer "Abyss Empire" - als
      KURZBESCHREIBUNG.md im store/-Ordner ablegen.
- [x] **ST5 - 10-Sekunden-App-Trailer:**
      Simpler Trailer: Spielszenen (Screen-Recordings vom
      Emulator), Text-Einblendungen ("Baue dein Riff", "Erobere
      die Tiefsee", ...), einfache Animationen (Fades, Zooms) -
      Tooling auf dem Host (z. B. ffmpeg-Pipeline), Ausgabe als
      MP4 in store/trailer/. Kein App-Code noetig.

## Abnahme-Kriterium 1.2.13-a

**Fertig wenn:**
1. store/-Ordner existiert mit Screenshots (>= 4 Kernszenen,
   Formate dokumentiert), KURZBESCHREIBUNG.md, Trailer-MP4
   (10 s, Spielszenen + Text + Fade/Zoom).
2. BESCHREIBUNG.md auf dem Stand der Version.
3. Alles committet; KEIN App-Build noetig (keine versionCode-
   Erhoehung) - ausser der Check ergibt App-Anpassungen (dann
   dokumentieren).

## Aufwand 1.2.13-a
| Aufgabe | Aufwand |
|---------|---------|
| ST1 (BESCHREIBUNG)      | 0,5 |
| ST2 (Ordner)             | 0,25 |
| ST3 (Screenshots)         | 0,5-1 |
| ST4 (Kurzbeschreibung)    | 0,5 |
| ST5 (Trailer)              | 1,5-2 |

## Status 1.2.13-a (fertig - Store-Materialien, kein App-Build)

Umsetzung:
1. ST1: BESCHREIBUNG.md von Stand 1.1.3 auf 1.2.12 aktualisiert:
   10x10-Seekarte (99 Nebel-Zonen), Steinkoralle, x10-Handel,
   Produktions-Anzeige, Anglerfisch-Leuchtfeuer, Sound-Modi,
   Schwierigkeitsstufen, 45-s-Ambient-Loop, Adaptive-Icon-Absatz,
   Highscore; technischer Stand (versionCode 24, ~137 KB, 309 Tests)
   und store/-Verweis ergaenzt. Links unveraendert gueltig.
2. ST2: store/ mit README.md (Struktur-, Format- und Nachweis-Doku),
   screenshots/, trailer/ (+ trailer/raw/ fuer Roh-Material).
3. ST3: 6 Emulator-Screenshots (2400x1080 Landscape): Welt mit
   Welle (170 HP-Balken-Pixel), Bau-Menue, Seekarte, Instinkte,
   Game-Over, Highscore - jede Szene per Pixel-Nachweis verifiziert.
4. ST4: KURZBESCHREIBUNG.md mit 74-Zeichen-Haupthinweis ("Baue dein
   Haie-Rudel auf, verteidige dein Riff und erobere die Tiefsee!")
   und 384-Zeichen-Volltext.
5. ST5: abyss-empire-trailer.mp4 - exakt 10,00 s, 1920x1080, 30 fps,
   h264 + stummer AAC-Track, faststart, 532.851 Bytes. Inhalt: Welt+
   Welle mit langsamem Zoom und "BAUE DEIN RIFF" (Alpha-Fade),
   Crossfade zur Seekarte mit "EROBERE DIE TIEFSEE", Crossfade zur
   Endkarte "ABYSS EMPIRE - Der Schrecken der Tiefe", Fade-in/out.
   Pixel-Nachweis der Titel (651/1134 weisse Sampler) und Frame-
   Extraktion dokumentiert. Reproduzierbare zweistufige Pipeline in
   build-trailer.sh (zoompan + xfade im selben Graph brechen den
   Filter-Init - Clips werden einzeln gerendert, dann verbunden).

Werkzeug-Notizen (fuer Nachziehen): ffmpeg 9.0.2 via winget
(Gyan.FFmpeg) auf dem Host installiert; adb-screenrecord braucht in
Git Bash den Geraetepfad als //sdcard/... (MSYS-Pfadmunglung);
Wellen-Timing fuer Action-Szenen: Aufnahme ~15-20 s nach Wellen-
Spawn, Riff faellt nach weiteren ~30 s.

Abnahme: KEIN App-Build noetig (kein Code geaendert, versionCode
bleibt 24). Committet: store/ (Screenshots, Trailer + Roh-Material,
Pipeline, README, KURZBESCHREIBUNG.md) + BESCHREIBUNG.md + Roadmap.
Grenzen (ehrlich): Screenshots nur Landscape (App ist Landscape-
only, Store-Hochkant-Slots braeuchten eigene Skalierung); Trailer
ohne echte Spieltöne (stummer Track; Sound-Untermalung als optionaler
Folgeschritt); Feature-Grafik (512x1024 Phone-Hero) noch offen
(1.2.13-b-Checkliste).

---

# Version 1.2.13-b – Release-/Veroeffentlichungs-Analyse (nach 1.2.13-a)

## Aufgaben 1.2.13-b

- [x] **RA1 - Technische Release-Analyse:**
      Was fehlt fuer die Veroeffentlichung: Play-Store-Konto/
      Signing (Keystore-Strategie: Upload-Key vs. App-Signing,
      Keystore-Backup!), Target-/Min-SDK-Politik (Store-API-
      Anforderungen), App Bundle (AAB) statt APK, ProGuard-Mapping-
      Upload, Datenschutzgrundsaetze (Daten: nur lokale
      SharedPreferences - keine Netz-/Tracking-APIs, kurz
      dokumentieren), Content-Rating-Fragebogen, Altersfreigabe,
      Berechtigungen (Manifest pruefen und dokumentieren),
      VersionCode-Reserve, Store-Listing-Felder (Screenshots/Texte
      aus 1.2.13-a einpflegen). Ergebnis als Checkliste mit
      Status offen/erledigt.
- [x] **RA2 - Bericht:**
      Die Checkliste in der Roadmap dokumentieren; Empfehlung,
      welche Punkte vor dem ersten Upload Pflicht sind (Signing-
      Backup!, AAB, Datenschutztext) und welche optional bleiben.
      Kein App-Code - Analyse-Commit.

## Abnahme-Kriterium 1.2.13-b

**Fertig wenn:**
1. Vollstaendige Release-Checkliste (technisch + Store-Prozess)
   mit Status und Empfehlung dokumentiert.
2. Kein offener Punkt ueberraschend: alles, was App-Code braeuchte,
   ist als eigene Roadmap-Version markiert.

## Aufwand 1.2.13-b
| Aufgabe | Aufwand |
|---------|---------|
| RA1 (Checkliste) | 0,5-1 |
| RA2 (Bericht)     | 0,25 |

## Status 1.2.13-b (fertig - Release-Checkliste, kein App-Code)

RA1 - Checkliste (vermessen am Repo, Stand 1.2.13-a):

A. App-/Binaer-Technik:
| # | Punkt | Status | Befund |
|---|---|---|---|
| 1 | Berechtigungen | ERL | Manifest hat NULL permissions (kein INTERNET, kein Tracking) - "keine Berechtigungen" ist store-faehig |
| 2 | Keystore-Disziplin | ERL/OFFEN | release.keystore + keystore.properties stehen korrekt in .gitignore (nicht im Repo) - existieren NUR lokal auf dem Entwickler-Rechner: BACKUP PFLICHT vor jedem Upload |
| 3 | Play App Signing | OFFEN | Beim ersten Upload Enrollment durchfuehren (Google haelt den App-Signing-Key, Upload-Key bleibt lokal) - schuetzt bei spaeterem Keystore-Verlust |
| 4 | R8/Minify | ERL | isMinifyEnabled + shrinkResources aktiv; mapping.txt (build/outputs/mapping/release/) pro Release archivieren (Prozess, kein Code) |
| 5 | AAB statt APK | OFFEN | Play verlangt fuer NEUE Apps Android App Bundle: `./gradlew bundleRelease` statt assembleRelease - kein Code, beim Upload ausfuehren |
| 6 | SDK-Politik | ERL | minSdk 24, targetSdk 36, compileSdk 36 - aktuelle Play-Target-API-Pflicht erfuellt; kuenftige API-Jahrespflicht beobachten |
| 7 | 64-Bit/Groesse | ERL | kein NDK (automatisch 64-Bit-faehig im Bundle); ~137 KB weit unter allen Limits |
| 8 | versionCode/versionName | ERL | versionCode 24 verbraucht, Reserve ok; versionName 1.2.10 hinkt der Dokumentation (1.2.12) hinterher - naechster Code-Build (25) synchronisiert, kein Store-Blocker |

B. Store-Prozess (ausserhalb des Repos, User-Aktionen):
| # | Punkt | Status | Befund |
|---|---|---|---|
| 9 | Play-Console-Konto | OFFEN | Einmalig 25 USD (User) - Voraussetzung fuer alles Folgende |
| 10 | Listing-Texte | ERL | Titel "Abyss Empire" (12/30 Zeichen), Kurzbeschreibung 74/80 (store/KURZBESCHREIBUNG.md), Volltext (docs/BESCHREIBUNG.md) |
| 11 | Screenshots | ERL | 6 Landschaft-Screenshots in store/screenshots/ (Play akzeptiert Landscape; Hochkant-Slots optional) |
| 12 | Trailer | ERL | 10-s-MP4 in store/trailer/ (Play-Format 1920x1080 h264+aac) |
| 13 | Store-Icon 512x512 PNG | ERL | Listing braucht eine 512er-PNG neben dem Adaptive Icon - aus Vordergrund/Hintergrund rendern (store-Asset, kein App-Code): erledigt als store/graphics/store-icon-512.png (Nachtrag zur Checkliste, pixelverifiziert) |
| 14 | Feature-Grafik 1024x500 | ERL | Pflichtfeld im Listing - erledigt als store/graphics/feature-graphic.png (Tiefsee-Verlauf + Titel + Hai, pixelverifiziert); beide Grafiken reproduzierbar ueber store/graphics/build-graphics.ps1 |
| 15 | Datenschutzgrundsaetze | ERL/OFFEN | App erhebt/teilt NICHTS (nur lokale SharedPreferences, keine Netz-API) - Formular einfach; Privacy-Policy-Text liegt fertig in store/DATENSCHUTZ.md (Nachtrag zur Checkliste); PFLICHT bleibt das Hosting unter einer oeffentlichen URL auf hoatzin-development.de (Kontakt in Abschnitt 1 ergaenzen, dann hochladen) |
| 16 | Content-Rating (IARC) | OFFEN | Fragebogen im Console-Dialog; Fantasy-Gewalt (Hai jagt, Revierkaempfe) ohne realistische Gewalt -> voraussichtlich PEGI 3/ohne Altersbeschraenkung |
| 17 | Zielgruppe/Ads/IAP | OFFEN | Console-Fragebogen: keine Ads, keine In-App-Kaeufe, Zielgruppe 13+ - keine Vorbereitung noetig |
| 18 | Test-Track | OFFEN | Empfehlung: erster Upload in den internen Testtrack, dann Produktion |

RA2 - Empfehlung (Pflicht vor erstem Upload, sortiert):
1. Keystore-Backup anlegen (externer Ort!) und Play-App-Signing-
   Enrollment - ohne beides ist ein Keystore-Verlust ein Update-Stopp.
2. bundleRelease (AAB) statt APK hochladen; mapping.txt archivieren.
3. Privacy-Policy-URL (Datensparsamkeit ist ideal: "keine Daten" -
   aber die URL ist Pflichtfeld).
4. Store-Icon 512x512 + Feature-Grafik 1024x500 nachliefern
   (store/-Assets, halbe Stunde Arbeit, kein App-Code).
5. Console-Konto + die drei Frageboegen (Datenschutz, Content-
   Rating, Zielgruppe) - reine Dialog-Arbeit.
Kein einziger offener Punkt benoetigt App-Code: Es ist KEINE weitere
Roadmap-Version fuer den Upload noetig. Die beiden Store-Grafiken (#13/
#14) und der Privacy-Policy-Text sind die einzigen noch fehlenden
Artefakte und koennen auf Anfrage als store/-Ergaenzung entstehen
(dokumentiert, ohne eigene Version).

Abnahme: Analyse-only-Commit (Muster 1.2.1/N3) ohne versionCode-Build.
Working Tree blieb code-massig unberuehrt; 309 Tests unveraendert gruen
(Stand 1.2.12).