1e51ef7def
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/ - 12 code-workspace-Files - STATUS-*.md - viele M/D/R-Änderungen an bereits getrackten Files - .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
524 lines
20 KiB
Markdown
524 lines
20 KiB
Markdown
# GeoGraSim — Sim-Spec für externe KI-Entwicklung
|
||
|
||
**Stand: 2026-06-12** · Ergänzung zu [`module-interface.md`](module-interface.md) und [`integration-konzept.md`](integration-konzept.md).
|
||
|
||
> **Wichtig:** Dieses Dokument fasst nur das Neue / Geänderte seit Juni 2026 zusammen und bündelt die für eine externe KI essentiellen Schnittstellen. Die historischen Files bleiben gültig für: Sprache (Lernarbeit statt Spiel · Leichte Sprache), iPad-Pattern, Persistenz/Resume, Datei-Struktur, Datenmodell-Grundlagen.
|
||
|
||
---
|
||
|
||
## 0. TL;DR — Was eine neue Sim aus Plattform-Sicht ist
|
||
|
||
```
|
||
App/sims/<sim-id>/game.html ← deine HTML-Datei
|
||
App/sims/<sim-id>/engine.js ← optional, separate JS-Logik
|
||
App/sims/<sim-id>/assets/ ← optional, sim-eigene Bilder/Sounds
|
||
|
||
App/pages/<sim-id>.php ← PHP-Wrapper (Plattform-Standard, Atlas legt an)
|
||
```
|
||
|
||
Plus 1 Eintrag in der DB-Tabelle `module_info` (Title, Icon, Status, sort_order — Atlas macht das).
|
||
|
||
Die Sim selbst ist ein **selbst-laufender Browser-Frontend-Block**. Sie spricht mit der Plattform NUR über die 4 Window-Globals (siehe §2) und einen einzigen HTTP-Endpoint `/api/progress.php` zum Speichern (siehe §3).
|
||
|
||
---
|
||
|
||
## 1. Plattform-Conventions (Stand Juni 2026)
|
||
|
||
Drei Window-Globals + ein optionales Lib. Vollständige Doku im Header von [`/assets/js/live-client.js`](../assets/js/live-client.js).
|
||
|
||
### 1.1 `window.__GGS__` — Plattform setzt, Sim liest
|
||
|
||
Wird vom PHP-Wrapper VOR der Sim-Logik gesetzt:
|
||
|
||
```js
|
||
window.__GGS__ = {
|
||
sessionId: 'uuid', // anonyme Session
|
||
studentId: 12, // optional, null bei Gast
|
||
classId: 3, // optional
|
||
simId: 'kofferdetektiv',
|
||
simName: 'Kofferdetektiv',
|
||
level: 1,
|
||
baseUrl: '/geograsim/App', // oder '' auf Prod
|
||
apiUrl: '/geograsim/App/php/api',
|
||
basePath: '/geograsim/App',
|
||
mode: 'free', // 'free' | 'teacher_started' | 'locked'
|
||
forcedLevel: null, // wenn 'teacher_started': Pflicht-Level
|
||
easy: false, // Leichte Sprache aktiv?
|
||
};
|
||
```
|
||
|
||
Wenn `__GGS__` nicht da ist, läuft die Sim trotzdem (Dev/Direkt-URL) — sie sollte robust mit `undefined` umgehen.
|
||
|
||
### 1.2 `window.GGS_LIVE_STATE` — Sim setzt eine Funktion
|
||
|
||
Funktion, die einen Snapshot des aktuellen Sim-Zustands zurückgibt. Wird vom Plattform-Live-Client alle 4 s aufgerufen und ans Lehrer-Cockpit gestreamt.
|
||
|
||
```js
|
||
window.GGS_LIVE_STATE = function () {
|
||
if (!gameReady) return null;
|
||
return {
|
||
simId: 'kofferdetektiv',
|
||
phase: 'fall-3-zoll', // freier Text — was passiert gerade
|
||
progressPct: 60, // 0-100, didaktische Empfehlung
|
||
score: 42, // wenn schon scorebar
|
||
health: 'good', // good | ok | struggle (für Status-Punkt)
|
||
// weitere sim-spezifische Felder — Cockpit picked sich, was es kann
|
||
};
|
||
};
|
||
```
|
||
|
||
**Fallstrick** (echter Bug von Fluss am 2026-06-11): Nutze KEINE Property `params` auf einem Objekt, wenn `params` nicht direkt darauf existiert. `if (!game.params)` true → Snapshot null → Cockpit zeigt „meldet keine Live-Werte" obwohl die Sim läuft. Lies State direkt aus dem Computed-Result.
|
||
|
||
### 1.3 `window.GGS_TUTORIAL` — Sim registriert Replay-Hook
|
||
|
||
Damit der ℹ-Button im Header das Onboarding nochmal öffnet:
|
||
|
||
```js
|
||
window.GGS_TUTORIAL = {
|
||
simId: 'kofferdetektiv',
|
||
title: '🕵️ Kofferdetektiv',
|
||
replay: function () { startTutorial(); }, // deine eigene Funktion
|
||
};
|
||
```
|
||
|
||
Der Button wird in der Sim selbst eingefügt (siehe §4.2 Header-Standard).
|
||
|
||
### 1.4 `window.__GGS_LIVE__` — Plattform setzt, Sim liest
|
||
|
||
Read-only Proxy, von [`live-client.js`](../assets/js/live-client.js) bereitgestellt:
|
||
|
||
```js
|
||
window.__GGS_LIVE__ = {
|
||
activeMs: number, // aktive Spielzeit (gecappt bei 7_200_000 = 120 min)
|
||
idleMs: number, // Zeit seit letzter Interaktion
|
||
sessionStartedAt: timestamp,
|
||
lastInteractionAt: timestamp,
|
||
capped: boolean,
|
||
MAX_SESSION_MS: 7200000,
|
||
IDLE_THRESHOLD_MS: 90000,
|
||
};
|
||
```
|
||
|
||
**Wann lesen:** Beim Submit als `duration_ms` — bitte `__GGS_LIVE__.activeMs` statt `Date.now() - start` benutzen. Sonst landet auch Idle-Zeit (Tab vergessen) in der DB. Plattform-Cap zusätzlich im Backend defensiv.
|
||
|
||
### 1.5 Reservierte `__`-Heartbeat-Keys
|
||
|
||
Der Live-Client mischt automatisch in jeden `GGS_LIVE_STATE`-Snapshot:
|
||
|
||
```
|
||
state.__activeMs, state.__idleMs, state.__lastInteractionAt,
|
||
state.__sessionStartedAt, state.__capped
|
||
```
|
||
|
||
**Niemals überschreiben** — Cockpit liest diese aus.
|
||
|
||
---
|
||
|
||
## 2. Plattform-Bibliotheken (optional einbindbar)
|
||
|
||
### 2.1 Glossar-Tooltip
|
||
|
||
```html
|
||
<script src="/assets/js/glossar-tooltip.js" defer></script>
|
||
<script>
|
||
window.addEventListener('DOMContentLoaded', () => {
|
||
GlossarTooltip.init({
|
||
apiBase: '/php/api',
|
||
moduleId: 'kofferdetektiv', // filtert DB auf sim-eigene Begriffe
|
||
});
|
||
});
|
||
</script>
|
||
```
|
||
|
||
Im Markup:
|
||
```html
|
||
<span class="ggs-g" data-glossar="zollkontrolle">Zollkontrolle</span>
|
||
```
|
||
|
||
Wirkung: Tap/Klick → Popup mit Kurztext + Link zum vollen Glossar-Eintrag. Tooltip-CSS wird automatisch injiziert. Hat zentralen Style — nicht selbst CSS für `.ggs-g` schreiben.
|
||
|
||
Vorgehen für neue Glossar-Begriffe: in der DB-Tabelle `glossar` anlegen, `module_id` setzen. Atlas oder Glossar-Instanz macht das.
|
||
|
||
### 2.2 Quick-Intro (Mini-Onboarding-Modal)
|
||
|
||
Für Sims OHNE volles Tutorial. Bietet ein einheitliches Modal beim 1. Besuch + Replay-Funktion.
|
||
|
||
```html
|
||
<script src="/assets/js/ggs-quick-intro.js" defer></script>
|
||
<script>
|
||
window.addEventListener('DOMContentLoaded', () => {
|
||
GgsQuickIntro.init({
|
||
simId: 'kofferdetektiv',
|
||
title: '🕵️ Kofferdetektiv',
|
||
lead: 'Du untersuchst beschlagnahmte Koffer am Flughafen. Was darf rein, was nicht — und warum?',
|
||
steps: [
|
||
'Koffer öffnen — du siehst Inhalt + Herkunft + Zielland.',
|
||
'Gegenstände prüfen — viele Vorschriften erschließen sich aus Geografie + Politik.',
|
||
'Entscheidung treffen: durchlassen, beanstanden oder beschlagnahmen.',
|
||
'Feedback bekommen — pro Entscheidung Lehrtext + Glossar.',
|
||
],
|
||
goals: [
|
||
'Zoll- und Einreisebestimmungen verstehen',
|
||
'Herkunftsländer von Produkten geografisch einordnen',
|
||
'Gesetzeskunde im Kontext (Artenschutz, Drogen, Lebensmittel)',
|
||
],
|
||
});
|
||
});
|
||
</script>
|
||
```
|
||
|
||
Verhalten: 1. Besuch → Modal auto-open. localStorage merkt sich „gesehen" (`ggs.intro.<simId>`). Library registriert automatisch `window.GGS_TUTORIAL.replay()`. ℹ-Header-Button öffnet das Modal wieder.
|
||
|
||
Du kannst alternativ ein **volles, sim-spezifisches Tutorial** bauen (mehrere Schritte mit Bildern + Glossar-Begriffen — siehe weltkueche/game.html als Referenz). Dann musst du nur `window.GGS_TUTORIAL = {simId, title, replay: deineFunktion}` selbst setzen.
|
||
|
||
### 2.3 Live-Client (live-client.js)
|
||
|
||
Wird vom PHP-Wrapper automatisch eingebunden — Sim muss nichts tun. Library trackt Idle (siehe §1.4), sendet Heartbeats an `/api/live.php`, pollt Pause-Flag.
|
||
|
||
---
|
||
|
||
## 3. Submit-Pfad — Wie die Sim ihre Daten persistiert
|
||
|
||
Drei Aktionen via `POST /api/progress.php` mit JSON-Body. Auth läuft automatisch über die Session-Cookie aus `__GGS__`.
|
||
|
||
### 3.1 Live-Fortschritt (optional, alle paar Aktionen)
|
||
|
||
```js
|
||
fetch(__GGS__.apiUrl + '/progress.php', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
credentials: 'same-origin',
|
||
body: JSON.stringify({
|
||
sim_id: 'kofferdetektiv',
|
||
action: 'update',
|
||
data: { phase: 'fall-3', score: 42 },
|
||
}),
|
||
});
|
||
```
|
||
|
||
Selten nötig — GGS_LIVE_STATE deckt das eigentlich ab. Nur wenn du persistente Zwischenstände in der DB willst.
|
||
|
||
### 3.2 Reflexionsantwort (zwischen Phasen)
|
||
|
||
```js
|
||
fetch(__GGS__.apiUrl + '/progress.php', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
credentials: 'same-origin',
|
||
body: JSON.stringify({
|
||
sim_id: 'kofferdetektiv',
|
||
action: 'reflection',
|
||
data: {
|
||
level: 1,
|
||
question: 'Was war dein schwierigster Fall?',
|
||
answer: 'Der Koffer aus Kenia',
|
||
},
|
||
}),
|
||
});
|
||
```
|
||
|
||
### 3.3 Abschluss-Submit (Pflicht — am Ende einer Stufe)
|
||
|
||
```js
|
||
fetch(__GGS__.apiUrl + '/progress.php', {
|
||
method: 'POST',
|
||
headers: {'Content-Type': 'application/json'},
|
||
credentials: 'same-origin',
|
||
body: JSON.stringify({
|
||
sim_id: 'kofferdetektiv',
|
||
action: 'submit_assessment',
|
||
data: {
|
||
level: 1,
|
||
stars: 3,
|
||
score: 72,
|
||
duration_ms: (window.__GGS_LIVE__ && window.__GGS_LIVE__.activeMs) || 0,
|
||
completed: true,
|
||
results: {
|
||
// SIM-SPEZIFISCHE Felder. Die Plattform-Benchmark-Engine
|
||
// erwartet von dir konkrete Keys (siehe §5) — bitte mit Atlas
|
||
// abstimmen, bevor du das Schema festschreibst.
|
||
cases_solved: 8,
|
||
cases_total: 10,
|
||
correct_first_try: 6,
|
||
wrong_decisions: 1,
|
||
glossar_consulted: 4,
|
||
},
|
||
},
|
||
}),
|
||
});
|
||
```
|
||
|
||
**Wichtig:** `results` ist sim-spezifisches JSON. Es wird in `assessments.results` als String gespeichert und sowohl im Lehrer-Cockpit (live.php) als auch im Ergebnisse-Tab (results.php) ausgelesen. Konventionen pro Sim folgen aus der Benchmark-Formel — siehe §5.
|
||
|
||
---
|
||
|
||
## 4. Design-System (Pflicht)
|
||
|
||
CSS-Variablen + Layout-Klassen aus [`/assets/css/design-system.css`](../assets/css/design-system.css).
|
||
|
||
### 4.1 Farb-Variablen
|
||
|
||
```css
|
||
--ggs-fjord /* Primärblau, Headlines */
|
||
--ggs-fjord-dark /* Dunkler Akzent */
|
||
--ggs-moss /* Erfolg/Grün */
|
||
--ggs-sand /* Kosten/Neutral */
|
||
--ggs-coral /* Gefahr/Rot */
|
||
--ggs-orange /* Warnung */
|
||
```
|
||
|
||
UI-Farben sind NICHT die Bild-Palette (siehe §6).
|
||
|
||
### 4.2 Header-Standard (Plattform-konform)
|
||
|
||
```html
|
||
<header class="ggs-header">
|
||
<a href="/schueler" class="ggs-header-logo">
|
||
<img src="/assets/img/bildLogo.png" alt="" class="ggs-header-logo-icon">
|
||
<img src="/assets/img/textlogo_geograsim.svg" alt="GeoGraSim" class="ggs-header-logo-text">
|
||
</a>
|
||
<div class="ggs-header-separator"></div>
|
||
<span class="ggs-header-module">Kofferdetektiv</span>
|
||
<span class="ggs-header-badge">Stufe 1</span>
|
||
|
||
<div class="ggs-header-spacer"></div>
|
||
|
||
<div class="ggs-header-actions">
|
||
<!-- Plattform-Standard: ℹ als ERSTER Button vor 📚 -->
|
||
<button class="ggs-btn-ghost" id="btn-info"
|
||
title="Anleitung nochmal zeigen"
|
||
onclick="if(window.GGS_TUTORIAL&&typeof window.GGS_TUTORIAL.replay==='function')window.GGS_TUTORIAL.replay();">ℹ</button>
|
||
<a class="ggs-btn-ghost" id="ggs-lehrplan-link" href="#" target="_blank" title="Lehrplan-Bezug">📚</a>
|
||
<button class="ggs-btn-ghost" id="btn-mute" title="Ton aus/an">🔊</button>
|
||
<button class="ggs-btn-ghost" id="btn-reset" title="Fortschritt zurücksetzen">🔄</button>
|
||
<a href="/schueler" class="ggs-btn-ghost" title="Zurück zum Cockpit">🏠</a>
|
||
</div>
|
||
</header>
|
||
```
|
||
|
||
**Regel:** ℹ = Tutorial-Replay (Plattform-Convention). Wenn deine Sim einen anderen Info-Inhalt hat (z.B. Fachinfo/Glossar in Farmer), kommt der mit eigenem Icon — `📖` für Glossar, `📚` für Lehrplan.
|
||
|
||
### 4.3 Layout-Zonen
|
||
|
||
`ggs-sim-layout` 3-Spalten-Grid (Status links, Sim Mitte, Aktionen rechts). Details in [`module-interface.md`](module-interface.md) §5.
|
||
|
||
### 4.4 Cockpit-Sichtbarkeit (LIVE_PRIMARY_FIELDS)
|
||
|
||
Damit deine Sim im Lehrer-Cockpit sinnvolle Spalten zeigt, muss Atlas in [`teacher.html`](../teacher.html) einen `LIVE_PRIMARY_FIELDS['kofferdetektiv']`-Eintrag setzen. Beispiel:
|
||
|
||
```js
|
||
'kofferdetektiv': [
|
||
{k:'health', label:'Status', align:'center', fmt: v => LIVE_VALUE_LABELS.health[v] || '—'},
|
||
{k:'phase', label:'Phase'},
|
||
{k:'progressPct', label:'Fortschritt', fmt: v => _liveBar(v, 0, 100, 'mid')},
|
||
{k:'score', label:'🏅 Score', fmt: v => _liveBar(v, 0, 100, 'high')},
|
||
{k:'cases_solved', label:'Gelöst'},
|
||
{k:'correct_first_try',label:'1.-Versuch ✓'},
|
||
],
|
||
```
|
||
|
||
Range-Bars: Helfer `_liveBar(val, min, max, goodWhen)`. `goodWhen`: `'high'` (grün ab 60% Range), `'low'` (invers — niedrig=gut), `'mid'` (neutral grau).
|
||
|
||
**Vorgehen für externe KI:** Liefere Atlas einfach die Liste deiner GGS_LIVE_STATE-Felder + welche davon Range-Bars wert sind. Atlas patcht teacher.html.
|
||
|
||
---
|
||
|
||
## 5. Benchmark-Engine — Sim braucht eine Scoring-Formel
|
||
|
||
Die Plattform berechnet pro Submission einen 0–100-Modul-Score (für Lehrer-Cockpit Top 3 / Bottom 3 und Ergebnisse-Tab). Die Formel lebt in [`App/php/lib/Benchmark.php`](../php/lib/Benchmark.php) als private statische Methode.
|
||
|
||
Pro neuer Sim: **du lieferst die Formel-Idee, Atlas integriert sie**. Beispiel-Briefing (Kofferdetektiv):
|
||
|
||
```
|
||
scoreKofferdetektiv($results) {
|
||
$solved = $results['cases_solved'] ?? 0;
|
||
$total = $results['cases_total'] ?? 0;
|
||
$firstTry = $results['correct_first_try'] ?? 0;
|
||
$wrong = $results['wrong_decisions'] ?? 0;
|
||
if ($total === 0) return null;
|
||
$base = ($solved / $total) * 70; // 70 % Lösung
|
||
$bonus = ($firstTry / $total) * 30; // 30 % Sauberkeit
|
||
$malus = min(20, $wrong * 5); // bis -20 für Fehlentscheidung
|
||
return max(0, min(100, $base + $bonus - $malus));
|
||
}
|
||
```
|
||
|
||
Wichtig:
|
||
- Wenn keine bewertbaren Daten → `null` (lieber „noch keine Bewertung" als geratene Zahl).
|
||
- Pro Modul max. die 3 besten Sessions zählen — macht die Engine selbst.
|
||
|
||
---
|
||
|
||
## 6. Bildstil — Flat Scandinavian
|
||
|
||
Für ALLE Bilder in der Sim (Onboarding, Kategorie-Icons, Karten-Backgrounds, Charakter-Avatare):
|
||
|
||
**Palette:**
|
||
```
|
||
Background #e8e4d8 (warmer Sand)
|
||
Primär #1f4b37 (Forest)
|
||
Sekundär #4a7c4e (Moss)
|
||
Akzent #e8c547 (Honey)
|
||
Detail #b04a3e (Coral, sparsam)
|
||
```
|
||
|
||
**DALL-E-Prompt-Block (Standard):**
|
||
|
||
```
|
||
Flat scandinavian illustration, geometric shapes, soft warm color palette
|
||
(#1f4b37 forest, #4a7c4e moss, #e8c547 honey, #e8e4d8 sand background,
|
||
#b04a3e coral accent sparingly). No people unless explicit, no text, no
|
||
photo-realism. Clean educational style for children 10-14, Sek I.
|
||
[hier deine Sim-Szene]. Square 1024x1024.
|
||
```
|
||
|
||
Auflösungen:
|
||
- Onboarding-Karten: 1024×1024 → WebP, max 200 KB
|
||
- Sim-eigene Bilder: 512×512 oder 1024×1024 je nach Verwendung
|
||
- Glossar-Illustrationen: 512×512 (Atlas verwaltet das zentral)
|
||
|
||
Standorte: `App/sims/<sim-id>/assets/img/` für sim-eigene; `App/assets/img/glossar/` für Glossar.
|
||
|
||
---
|
||
|
||
## 7. Sprache (Pflicht — schon in [`module-interface.md`](module-interface.md) §4a)
|
||
|
||
Kurz zur Erinnerung:
|
||
|
||
| Nicht | Sondern |
|
||
|---|---|
|
||
| spielen, Spiel | arbeiten mit, Simulation, bearbeiten |
|
||
| Spieler:in | Lernende, Bearbeiter:in |
|
||
| Game Over | Ziel verfehlt / Durchgang beendet |
|
||
| Highscore | Beste Leistung |
|
||
| Lehrkraft | **Lehrperson** (österreichisches Pädagog:innen-Bildungsgesetz) |
|
||
|
||
Begründung: Wygotski-basierte Lernarbeit-Sprache. Wenn die Sim für Schüler:innen sichtbar wird, gilt das strikt.
|
||
|
||
Plus: Sek-I-Tonalität (10–14 Jahre). Nicht infantil, nicht erwachsen. Du-Form, aber höflich.
|
||
|
||
---
|
||
|
||
## 8. Persistenz, iPad-Pattern, Leichte Sprache
|
||
|
||
Alle drei sind in [`module-interface.md`](module-interface.md) abgehandelt und gelten weiter:
|
||
- **Persistenz (§7b):** localStorage Autosave + Server-Mirror, Reload führt nie zum Neustart, expliziter Reset-Button mit Bestätigung.
|
||
- **iPad (§4c):** 1180×820 Referenz, Touch-Ziele 36–40 px, kein Hover-Kleber, `font-size: 16px` für Inputs.
|
||
- **Leichte Sprache (§4b):** Plattform-DB liefert Easy-Varianten von Glossar/Lehrplan automatisch, wenn Lehrperson das pro Schüler:in setzt.
|
||
|
||
---
|
||
|
||
## 9. Workflow für eine neue Sim (Pragmatisch)
|
||
|
||
1. **Konzept-Skizze** an Atlas: Was lernen sie? Wie ist die Mechanik? Welche Stufen? Welche Lehrplan-Anbindung?
|
||
2. **Atlas legt an:**
|
||
- `module_info`-Eintrag (Title, Icon, Status='entwurf', sort_order)
|
||
- `App/pages/<sim-id>.php`-Wrapper
|
||
- Routing in `.htaccess`
|
||
- Glossar-Begriffe einsammeln (an Glossar-Instanz weitergeben)
|
||
3. **Externe KI baut** `App/sims/<sim-id>/`:
|
||
- `game.html` mit Plattform-Header + GGS_LIVE_STATE + GGS_TUTORIAL/QuickIntro
|
||
- Engine in JS (vanilla, kein Build-Step)
|
||
- Submit-Pfad bei Phasen-Ende
|
||
- localStorage-Autosave
|
||
4. **Atlas integriert:**
|
||
- `LIVE_PRIMARY_FIELDS['<sim-id>']` in teacher.html
|
||
- `Benchmark::score<SimName>()` in Benchmark.php
|
||
- Playwright-Tests in `.dontDeploy/playwright/tests/stufe1-smoke/`
|
||
- Deploy + Test
|
||
5. **Status auf `aktiv`** schalten (über admin-modules.html oder direktes SQL).
|
||
|
||
---
|
||
|
||
## 10. Test-Pattern (Stufe 1 Smoke)
|
||
|
||
Pro Sim mindestens 1 Test in `.dontDeploy/playwright/tests/stufe1-smoke/`:
|
||
|
||
```js
|
||
test('Sim kofferdetektiv · __GGS__ + live-client + GGS_LIVE_STATE', async ({ page }) => {
|
||
await page.goto('https://geograsim.at/kofferdetektiv');
|
||
await page.waitForTimeout(2500);
|
||
const info = await page.evaluate(() => ({
|
||
ggs: typeof window.__GGS__,
|
||
state: typeof window.GGS_LIVE_STATE,
|
||
tutorial: typeof window.GGS_TUTORIAL,
|
||
}));
|
||
expect(info.ggs).toBe('object');
|
||
expect(info.state).toBe('function');
|
||
expect(info.tutorial).toBe('object');
|
||
});
|
||
```
|
||
|
||
Existing Pattern in [`sim-platform-context.spec.js`](../../.dontDeploy/playwright/tests/stufe1-smoke/sim-platform-context.spec.js) deckt alle Sims ab — Atlas ergänzt deinen Sim-Slug dort.
|
||
|
||
---
|
||
|
||
## 11. Referenz-Sims als Vorbild
|
||
|
||
Wenn die externe KI ein gutes Vorbild für die Code-Struktur braucht:
|
||
|
||
- **`App/sims/weltkueche/game.html`** — full Tutorial-Pattern + Glossar-Tooltip in Tutorial-Texten + saubere Submit-Logik. Mittelgroß (~2000 LoC).
|
||
- **`App/sims/busfahrt/game.html`** — Karten-basierte Sim mit Quick-Intro statt full Tutorial. Topbar mit eigenem Styling.
|
||
- **`App/sims/eu-werkstatt/game.html`** — Drag-and-Drop / Card-Sorting-Pattern.
|
||
- **`App/sims/sonnensystem/game.html`** — 3D-Canvas (Three.js) + state-driven Aufgaben.
|
||
|
||
Die externe KI sollte **mindestens eine dieser Sims lesen**, bevor sie ihre eigene baut — um Plattform-Header, Glossar-Anbindung und Submit-Pattern abzukucken.
|
||
|
||
---
|
||
|
||
## 12. Was die externe KI explizit NICHT machen soll
|
||
|
||
- Keine eigenen URL-Routen / .htaccess-Eingriffe — Atlas macht das.
|
||
- Keine Schema-Änderungen an DB-Tabellen ohne Rückfrage.
|
||
- Keine API-Calls in Endpoints, die nicht in §3 stehen.
|
||
- Keine eigenen Plattform-Bibliotheken in `/assets/js/` ergänzen — wenn dir was zentral fehlt, melde es Atlas.
|
||
- Keine Spiel-Sprache. Ernsthaft — siehe §7.
|
||
- Keine echten KI-Calls IM Produkt (OpenAI/Claude/Anthropic-API). Auswertung ist parametrisch. (Tutorial-Inhalte mit KI vorgenerieren ist OK, im Produkt landet das als statischer Content.)
|
||
|
||
---
|
||
|
||
## 13. Erstkontakt-Briefing für die externe KI (Copy-Paste)
|
||
|
||
```
|
||
Du baust ein neues GeoGraSim-Sim-Modul namens "<sim-id>".
|
||
Plattform-Kontext + Conventions: docs/sim-spec-2026-06-12.md (dieses Doc) +
|
||
docs/module-interface.md.
|
||
|
||
Hard Constraints:
|
||
- Vanilla HTML/JS/CSS. Kein Build-Step. Kein React/TypeScript.
|
||
- Plattform-Header genau wie in §4.2.
|
||
- window.GGS_LIVE_STATE() liefern (§1.2).
|
||
- window.GGS_TUTORIAL setzen oder ggs-quick-intro.js nutzen (§1.3 / §2.2).
|
||
- Submit am Ende via POST /api/progress.php (§3.3).
|
||
- duration_ms aus __GGS_LIVE__.activeMs lesen (§1.4).
|
||
- Sprache: Lernarbeit, nicht Spiel (§7).
|
||
- iPad-tauglich (siehe module-interface.md §4c).
|
||
- Persistenz: Reload darf nie neu starten (siehe module-interface.md §7b).
|
||
|
||
Liefere am Ende:
|
||
- App/sims/<sim-id>/game.html (+ engine.js wenn separat)
|
||
- Liste deiner GGS_LIVE_STATE-Felder + welche Range-Bars Sinn machen
|
||
- Vorschlag für Scoring-Formel (Benchmark §5)
|
||
- Glossar-Begriffe, die du im Tutorial verwendest
|
||
|
||
Atlas integriert dann teacher.html, Benchmark.php, .htaccess, DB.
|
||
```
|
||
|
||
---
|
||
|
||
## 14. Ansprechpartner & Files-Map
|
||
|
||
| Fragen zu | Wer / Wo |
|
||
|---|---|
|
||
| Plattform-API / live-client / Cockpit | Atlas, `/assets/js/live-client.js`, `/teacher.html`, `/php/api/live.php` |
|
||
| Submit-Endpoint, assessments-Schema | Atlas, `/php/api/progress.php`, `/php/api/assessment.php` |
|
||
| Benchmark-Formel pro Sim | Atlas, `/php/lib/Benchmark.php` |
|
||
| Glossar-Begriffe / Tooltip-Pattern | Glossar-Instanz / Atlas, DB-Tabelle `glossar` + `/assets/js/glossar-tooltip.js` |
|
||
| Lehrplan-Anbindung / Kompetenz-Mapping | Lehrplan-Instanz / Atlas, DB-Tabellen `kompetenzen`/`kompetenz_modules`/`lehrplan_anchors` |
|
||
| Design-System-Klassen | `/assets/css/design-system.css` |
|
||
| Bildstil + DALL-E-Prompts | Atlas, §6 hier + Memory `reference_bildstil` |
|
||
|
||
---
|
||
|
||
**Fragen?** An Atlas (Plattform-Instanz). Diese Spec wird laufend gepflegt — bei jeder neuen Convention bitte hier ein Update einreichen statt Side-Doc.
|