Roadmap
# 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).
