Files
Laby/docs/01_Debug_API.md
T
Lila-Kuh ea2a2f2cbf
Aegis CI / audit (push) Failing after 1m7s
Aegis CI / selfplay (push) Skipped
Aegis CI / perf (push) Failing after 3s
Aegis CI / report (push) Failing after 2s
Initial project version
2026-08-29 01:45:19 +02:00

5.8 KiB
Raw Blame History

01 Debug-API & In-Game-Console

Die Test-Orakel-Schicht des Games: window.__AEGIS_DEBUG__ und die eingebauten Audits. Die gesamte Test-Suite in tests/ hängt an dieser API sie ist die einzige stabile Schnittstelle zwischen den Skripten und der Game-Source.


1. Grundprinzip

Aegis-Labyrinth.html ist eine Single-File-App. Für Automatisierung stellt sie zwei Dinge bereit:

  1. window.__AEGIS_DEBUG__ ein explizit auf window gehängtes Objekt (stabil in page.evaluate() referenzierbar).
  2. Funktionen im Global Scope (placeTower, buySkill, simulate, triggerVictory, TOWER_TYPES, Game, …) frei verfügbar, aber const/let-basiert, d.h. nicht auf window.

Playwright-Fallstricke (WICHTIG)

Identifier Auf window? Referenz in page.evaluate()
__AEGIS_DEBUG__ ja window.__AEGIS_DEBUG__
TOWER_TYPES nein (const) TOWER_TYPES (bare)
Game nein Game (bare)
placeTower, buySkill, simulate nein bare Identifier

window.TOWER_TYPESundefined. Immer bare Identifier verwenden.


2. window.__AEGIS_DEBUG__ Komplette API

2.1 Audit-Funktionen

Funktion Prüft (Kurz)
runSelfAudit() Konnektivität aller 11 Levels, alle 9 Turm-Attacks, Skill-Käufe (4 Ränge), Platzierungs-Validierung, AutoWave, Endless-Transition
runExtensionAudit() Mortar-Splash (2 Ziele), Tesla-AoE (5 Feinde + Freeze), Reward-Dedup, Blocker-Alternate/Closed-Path
runRedesignAudit() Sniper-Priorisierung (niedriger HP zuerst), Quantum-Beam-Alignment, Nano-Spawner (Limit/Damage/Cleanup)

Jede Funktion gibt ein Report-Objekt zurück (Schema: 02_Audits.md).

2.2 State & Utility

window.__AEGIS_DEBUG__
├── runSelfAudit()           → report object
├── runExtensionAudit()      → report object
├── runRedesignAudit()       → report object
├── getState()               → { state, credits, lives, waveIndex, enemies, towers, … }
├── startEndlessLevel(n)     → startet Endless ab Level n (0-basiert)
├── selectLevel(n)           → lädt Level n (0-basiert)
├── startWave()              → manuelle Wave-Start
├── setCredits(n)            → Credits setzen
├── towerTypes[]             → 9 Einträge {id, name, cost, range, damage, fireRate, skills}
├── skilltree
│   ├── version, points, nodes, completed, endless20Rewards
│   ├── getState() → deep clone
│   ├── buy(nodeId)
│   └── reset()
├── levels[]                 → 11 Einträge {id, name, waves, difficulty, endlessAvailable}
├── effectMetadata
│   ├── towerTypes[] (ohne cost, mit skillIds)
│   ├── enemyTypes[] ({id, hp, speed, radius, color})
│   └── effectLimits ({maxParticles:200, maxProjectiles:100, maxHolos:20, particleLife:0.8, projectileLife:1.6})
├── effectTuning
│   ├── holo ({influenceRadius, pullStrength})
│   └── grav ({basePull, baseSlow})
├── aura
│   ├── getAuraState()
│   ├── getBonuses()
│   └── upgrade(tower)
└── audio
    ├── state() → {initialized, muted, volume, voices}
    ├── sounds[] → 20 Namen
    ├── test(name)
    ├── setMuted(bool)
    └── setVolume(01)

3. getState() typisches Schema

{
  state: "menu" | "playing" | "victory" | "defeat" | "endless",
  credits: number,
  lives: number,
  waveIndex: number,
  totalWaves: number,
  kills: number,
  leaked: number,
  enemies: number | Enemy[],   // je nach Version Zähler oder Array
  towers: number | Tower[],
  // …
}

Die Suite nutzt getState() primär als Beobachtungsschnittstelle für Self-Play & Perf. Exakte Felder: 02_Audits.md §getState.


4. In-Game-Debug-Console (manuell)

Aufruf: Im Browser mit Taste ` (Backtick) die Debug-Console öffnen.

Befehl Beschreibung
help Alle Befehle anzeigen
state Kompletten Game-State als JSON in der Konsole
credits [Zahl] Credits setzen (z. B. credits 99999)
unlock all Alle Türme entsperren
level [111] [normal|endless] Level laden (1-basiert)
wave Nächste Wave starten
audit [self|extension|redesign] Das entsprechende Audit ausführen
sound [Name] Sound testen (einer der 20 Sounds)
clear Konsole leeren

Die In-Game-Console ist für manuelle Debugging-Zwecke gedacht. Die automatisierte Suite nutzt direkt window.__AEGIS_DEBUG__ (ohne UI-Overlay).


5. Neue Mechanismen auditierbar machen (Konvention)

Jeder neue Mechanismus sollte vor Merge einen Audit-Eintrag in window.__AEGIS_DEBUG__ erhalten, damit tests/audit.mjs ihn automatisch abdeckt:

// Beispiel: neuer Turm "tesla2"
function runTesla2Audit() {
  loadLevel(0);
  const t = new Tower(TOWER_BY_ID.tesla2, 5, 5);
  const e = new Enemy('tank', t.x + 30, t.y);
  Game.towers = [t]; Game.enemies = [e];
  towerFire(t, 1/60);
  return { hit: e.hp < e.maxHp, beam: Game.beams.length > 0 };
}
window.__AEGIS_DEBUG__.runTesla2Audit = runTesla2Audit;

Anschließend die neue Funktion in tests/audit.mjs anbinden und hier + in 02_Audits.md dokumentieren.


6. Glossar (interner Jargon)

Begriff Bedeutung
grid[y][x] === 0 Bau-Kachel (Wand) Turm/Blocker hier erlaubt
grid[y][x] === 1 Pfad-Kachel Feinde laufen hier
grid[y][x] === 2 Start-Kachel (Entry)
grid[y][x] === 3 Exit-Kachel (Base)
flow.field[idx] === INF Zelle nicht erreichbar
NANITE_LIMIT Max. gleichzeitig aktive Naniten
autoWave / autoWaveActive Verzögerung zwischen Wellen
TOWER_BY_ID Map: "barrier" → Definition, "tesla" → Definition, etc.