Netzwerk-Labor · Doku đŸȘœ Hilfestellung – Stufen und Schnittstellen (verbindlicher Vertrag) Zum Spiel Online

đŸȘœ Hilfestellung – Stufen und Schnittstellen (verbindlicher Vertrag)

âŹ†ïž Netzwerk-Labor · Vertrag: Architektur · Spezifikation: Konzept – Netzwerk-Labor

Zweck. Das Labor soll einen Menschen ohne Syntaxkenntnis spielbar machen, ohne ihn zu langweilen, sobald er die Syntax kennt. DafĂŒr bekommt jede Ausbildungslage eine eigene Hilfe-Stufe mit einer messbaren Zahl von Hilfen. Dieser Text ist der Vertrag zwischen den Bausteinen — zuerst hier eintragen, dann bauen (AGENTS.md „Vertrag zuerst").

Grundsatz (aus dem Auftrag, 07.10.2026): Ein Azubi kann die ganzen Syntaxe nicht kennen, und im Spielflow hat er keinen Zugriff auf eine Lernnotiz. Also muss das Spiel die Hilfe dort anbieten, wo er steht: im Terminal, in der Leiste, im Trainingsbereich. Die Hilfe ist schrittweise — sie wĂ€chst mit dem Bildungsstand und mit dem Lernstand der einzelnen Fertigkeit.


§ 1 · Begriff: Bildungsstand ≠ ErklĂ€rtiefe ≠ Niveau

Drei Dinge hießen bisher „Niveau". Ab hier sind sie getrennt — daran hĂ€ngt jeder weitere Baustein.

BegriffFeldWerteWer liest das?
Bildungsstand (neu)Spiel.einst.stufe"azubi" · "azubi-plus" · "geselle" · "meister"Spiel.stufe.*, Terminal, Leiste, Trainingsbereich, Konsole, Simulation
ErklÀrtiefe (bestehend)Spiel.einst.niveau"E" · "AP1" · "AP2"UI.konsole (heute), Spiel.grundText
PrĂŒfungsstrenge je Ticket (bestehend)Spiel.einst.wahl, inst.niveau"auto" · "E" · "AP1" · "AP2"Spiel.niveauVon, Spiel.abnahme

Regel: Der Bildungsstand ist eine Voreinstellung des Menschen, kein Spielzustand und keine Automatik. Er wird nie automatisch geĂ€ndert. Spiel.einst.niveau (ErklĂ€rtiefe) wird beim Setzen des Bildungsstands mitgezogen, bleibt aber einzeln verstellbar — wer AP2-Texte bei Azubi-Hilfe will, darf das.

§ 2 · Die vier Stufen (Zahlen sind Vertrag)

stufe ist der Rang: azubi 1 · azubi-plus 2 · geselle 3 · meister 4. Vergleiche immer ĂŒber den Rang, nie ĂŒber den Namen.

azubi (1)azubi-plus (2)geselle (3)meister (4)
Wer1. Lehrjahr, kennt keine Syntax2.–3. Lehrjahr, kennt Grundbefehlekann den Job, ĂŒbt PrĂŒfungwill keine Hilfe
Terminal: Vorschlagsstreifen1 Vorschlag, mit Syntax + ErklÀrungbis 2 VorschlÀge, knappnur nach Fehlerkeiner
Terminal: „Was geht hier?"immer sichtbarsichtbarnach Fehlernein
Terminal: Befehls-GerĂŒst (zeige)ja (Befehl ausgeschrieben)ja, knapper Textneinnein
Terminal: Tipp zu falschem BefehlausfĂŒhrlich + Beispielknappknappnein
Terminal: Werkzeugleiteralle 6 Sprossen sichtbarsichtbarerst nach Fehlernein
Leiste/Mini: Hilfe-Knopfbei jeder Frage, stufenweise (2 Hilfen)bei jeder Frage (1 Hilfe)nur nach falscher Antwortnein
Leiste/Mini: Anker („wo steht das?")immer nach der Antwortnach der Antwortnur bei Fehlernein
Trainingsbereich: gefĂŒhrte Simulationangeboten, mit GerĂŒstangeboten, ohne GerĂŒstVorratslistenein
Simulation: GrĂŒnde in KlartextausfĂŒhrlich (E-Stufe)ausfĂŒhrlich (E-Stufe)knapp (AP1)nur Codes
Konsole (CLI): einstieg, Tippseinstieg:true, tipps:"alle"einstieg:true, tipps:"fehler"einstieg:false, tipps:"fehler"einstieg:false, tipps:"keine"

Hilfen sind schrittweise, nie alle auf einmal. Jede Stufe hat einen Vorrat (Kontingent), der mit jeder geöffneten Sprosse kleiner wird. Der Vorrat wird nur durch Hilfen verbraucht, nie durch Fehler.

Nachgetragen 07.10.2026 nach dem GegenprĂŒfungsbefund B1 von prĂŒfer-vertrag: Die ErklĂ€rtiefe ist eine eigene Achse (§ 1) und wird nicht vom Bildungsstand gesteuert — sie wird bei setzen() nur mitgezogen. Deshalb sind fĂŒr azubi und azubi-plus beide Male ausfĂŒhrliche Texte richtig: azubi-plus unterscheidet sich nicht durch kĂŒrzere Texte, sondern durch weniger und knappere VorschlĂ€ge (2 statt 1, knapper formuliert) und einen kleineren Vorrat (4 statt 6). Wer fĂŒr azubi-plus kĂŒrzere ErklĂ€rtexte will, verstellt die ErklĂ€rtiefe — die steht bewusst getrennt.

2.2 Wann erscheint eine Hilfe — zweite Abfrage, nicht zweite Wahrheit

Nachgetragen 07.10.2026 nach dem GegenprĂŒfungsbefund B2 von prĂŒfer-vertrag: Die Tabelle oben nennt fĂŒr die Werkzeugleiste, den Mini-Hilfe-Knopf und den Lernanker „erst nach Fehler" (geselle). Das ist keine Aussage darĂŒber, ob eine Stufe die FlĂ€che hat — das ist darf() —, sondern darĂŒber, wann sie erscheint. Beides muss abfragbar sein, sonst baut jede FlĂ€che die Bedingung selbst nach und es entstehen zwei Wahrheiten.

Spiel.stufe.darf("leiter" | "anker" | "miniHilfe" | "training")   // hat diese Stufe die FlĂ€che ĂŒberhaupt?
Spiel.stufe.wann("leiter" | "anker" | "miniHilfe")                // "immer" | "nachfehler" | "nein"
Spiel.stufe.wannPasst(flaeche, {fehler})                          // -> {ja, grund}

2.3 Abfragewege der Tabelle (Befund B3)

Nachgetragen 07.10.2026 nach dem GegenprĂŒfungsbefund B3 von prĂŒfer-vertrag: Zwei Zeilen der Tabelle hatten keinen Abfrageweg ĂŒber Spiel.stufe; wer sie je Stufe steuern wollte, hĂ€tte die Tabelle ein zweites Mal ausgewertet. Sie sind jetzt Teil der einen Tabelle:

Fragekann(...)darf(...)
„Was geht hier?" (GerĂŒst-Text je Modus)kann("wasGeht") → "immer" \"nachfehler" \"nein"darf("wasGeht") — abgeleitet: kann("wasGeht") !== "nein". Es gibt dafĂŒr bewusst keine zweite Tabelle.
Befehls-GerĂŒst (zeige)kann("geruest") → true \"knapp" \falsedarf("geruest") — eigener Schalter, weil "knapp" zwar vorhanden, aber nicht true ist.
Konsole: einstieg/tipps je Stufekann("einstieg"), kann("tipps")– (Werte, keine Schalter)

2.1 Vorrat (Kontingent) — verbindlich

Spiel.HILFE_KONTO = {azubi: 6, "azubi-plus": 4, geselle: 2, meister: 0}

§ 3 · Datenform: Spiel.stufe (neu)

Datei src/spiel/stufensystem.js — neu, ein Besitzer. Öffentliche FlĂ€che (nichts anderes aufrufen):

Spiel.STUFE = [
  /* Jede Zeile der Tabelle § 2 hat hier ihren Wert — auch die drei Spalten aus § 2.3. */
  {id:"azubi",      rang:1, name:"Azubi (1. Lehrjahr)", kurz:"Azubi", niveau:"E", tipps:"alle", vorschlaege:1,
   leiter:"immer", erklaerung:"ausfuehrlich", wasGeht:"immer", geruest:true, einstieg:true},
  {id:"azubi-plus", rang:2, name:"Azubi (fortgeschritten)", kurz:"Azubi+", niveau:"E", tipps:"fehler", vorschlaege:2,
   leiter:"immer", erklaerung:"ausfuehrlich", wasGeht:"immer", geruest:"knapp", einstieg:true},
  {id:"geselle",    rang:3, name:"Geselle / PrĂŒfungsvorbereitung", kurz:"Geselle", niveau:"AP1", tipps:"fehler", vorschlaege:1,
   leiter:"nachfehler", erklaerung:"knapp", wasGeht:"nachfehler", geruest:false, einstieg:false},
  {id:"meister",    rang:4, name:"Meister / Profi", kurz:"Meister", niveau:"AP2", tipps:"keine", vorschlaege:0,
   leiter:"nein", erklaerung:"nurcodes", wasGeht:"nein", geruest:false, einstieg:false},
];

Spiel.stufe.alle()            // -> Spiel.STUFE (Kopie, nie das Original)
Spiel.stufe.id()              // -> aktueller Bildungsstand, Standard "azubi"
Spiel.stufe.def(id?)          // -> Eintrag
Spiel.stufe.rang(id?)         // -> 1..4
Spiel.stufe.setzen(id, {still}?)   // setzt einst.stufe + zieht einst.niveau nach; sendet "stufe" + "niveau"
Spiel.stufe.kann(frage)       // -> Wert aus der Tabelle: vorschlaege, tipps, niveau, einstieg, wasGeht,
                              //    geruest, leiter, erklaerung; kann("konto") -> Zahl
Spiel.stufe.darf(frage)       // -> true/false: HAT diese Stufe die FlÀche? ("leiter", "anker", "miniHilfe",
                              //    "training", "geruest" aus der Schaltertabelle; "wasGeht" ABGELEITET)
Spiel.stufe.wann(flaeche)     // -> "immer" | "nachfehler" | "nein"   WANN erscheint die FlÀche? (§ 2.2)
Spiel.stufe.wannPasst(flaeche, {fehler})  // -> {ja, grund}  wertet die Bedingung aus – siehe § 2.2
Spiel.stufe.erklaerung()      // -> "ausfuehrlich" | "knapp" | "nurcodes"
Spiel.stufe.konto()           // -> {frei, gesamt} fĂŒr die offene Instanz (null ohne Instanz)
Spiel.stufe.hilfenFrei([inst])// -> nur die Zahl (fĂŒr eine Zeile „noch 3 von 6 Hilfen")
Spiel.stufe.hilfeZiehen(inst) // -> {frei:boolean, grund}  verbraucht EINE freie Hilfe, wenn vorhanden
Spiel.stufe.text(ausfuehrlich, knapp, nurcodes)  // -> den Text der Stufe (nie null)
Spiel.stufe.erklaerungText(id?)  // -> eine Zeile fĂŒr die OberflĂ€che (kein DOM)
Spiel.stufe.freigabeText(id?)    // -> eine Zeile „was ist gerade frei" (kein DOM)

Regeln:

  1. Kein Aufruf darf werfen, wenn einst.stufe fehlt oder unbekannt ist → RĂŒckfall "azubi".
  2. Spiel.stufe liest nie L (Lernmotor) — die Stufe ist eine Voreinstellung, der Lernstand kommt woanders her.
  3. Spiel.stufe.setzen schreibt ĂŒber Spiel.einstSetzen (nicht direkt in store), damit die OberflĂ€che es merkt.
  4. Deterministisch: kein Math.random, kein Date.now in dieser Datei.
  5. Wer eine Hilfe-FlĂ€che baut, fragt darf() UND wannPasst() — nie nur eines von beiden, und baut die Fehler-Regel nicht selbst nach (§ 2.2).

§ 4 · Terminal-Hilfe: Datenform DATEN.vorschlaege

Neue Datei src/daten/hilfen.js — Datenpaket, ein Besitzer. Der Kern ruft es ĂŒber Spiel.hilfe.passend(...), nie ĂŒber direkte Tabellenzugriffe aus der OberflĂ€che.

DATEN.hilfen.VORSCHLAEGE = [
  { id: "link-pruefen",           // eindeutig, stabil, PrÀfix nach Bereich
    bereich: "link",              // = Spiel.LEITER[].id, damit Leiter und Vorschlag dieselbe Sprache sprechen
    skills: ["lab.link"],         // Fertigkeiten, bei denen das passt
    befehl: "show ip interface brief",   // was im Terminal steht (leer = kein Befehl)
    erklaerung: "Überblick: jede Schnittstelle mit Adresse und Status.",  // EIN Satz, warum
    syntax: "show ip interface brief",   // Muster zum Lernen, ggf. mit <Platzhalter>
    geraet: "ios",                // "ios" | "host-windows" | "host-linux" | "fw" | "alle"
    modus: ["priv","config"],     // zulÀssige CLI-Modi, leer = alle
    ebene: 1,                     // 1..3  (1 = harmlos ansehen, 3 = Àndert etwas)
    art: "pruefen"                // "pruefen" (Ă€ndert nichts) | "aendern" (Ă€ndert Konfiguration)
  }, 

];

DATEN.hilfen.GERUEST = {          // „Was geht hier?“ je Modus — Text, kein Befehl
  ios: {user: "
", priv: "
", config: "
", if: "
", vlan: "
", dhcp: "
", 
},
  "host-windows": {
}, "host-linux": {
}, fw: {
}
};

DATEN.hilfen.SYNTAX = {           // Syntax-BrĂŒcke: „ich will X" -> „so schreibt man das"
  "ip-adresse-setzen": {titel:"IP-Adresse setzen", ios:"ip address <IP> <Maske>", host:"netsh interface ip set address 
", 
}
};

4.1 Der Vorschlagsstreifen (src/ui/hilfe.js, PrÀfix hl-)

UI.hilfe.zeichnen(container, {netz, geraetId, modus, sitzung, letzterFehler}) — die OberflĂ€che kennt die Sitzung, weil UI.konsole sie hĂ€lt. Entscheidung liegt in Spiel.hilfe, nicht in der OberflĂ€che:

Spiel.hilfe.passend({netz, id, modus, art, verlauf, letzterFehler, max})  // -> [{
vorschlag, warum}]
Spiel.hilfe.geruest({netz, id, modus, art})                               // -> string | null
Spiel.hilfe.leiter({netz, id, skill})                                     // -> Spiel.LEITER + {vorschlag}
Spiel.hilfe.syntaxBruecke({netz, id, modus, text, fehler})                // -> {titel, muster, beispiel} | null

Wo es hĂ€ngt (verbindlich, sonst ist es wirkungslos — AGENTS.md „Wirkung vor GrĂŒn"): UI.konsole.oeffnen hĂ€ngt den Streifen unter den Schirm, UI.konsole.ausfuehren ruft UI.hilfe.aktualisieren(K, {letzterFehler: r}) nach jeder Zeile auf, und UI.konsole.vorschlag (der bestehende E-Vorschlag) wird durch Spiel.hilfe gespeist, damit es nur eine Vorschlagsquelle gibt.

§ 5 · Leiste/Mini: Lernanker

Spiel.mini bekommt nichts Neues an Datenformen, nur zwei FlÀchen:

Spiel.mini.hilfe(id)        // -> {text, art:"denkhilfe"|"ausschnitt", frei:boolean}   stufenweise, je Frage
Spiel.mini.anker(id)        // -> {titel, text, quelle, wiki:skillId} | null           nach der Antwort

§ 6 · Trainingsbereich: Spiel.training

Neue Datei src/spiel/training.js — Simulationen abseits der AuftrĂ€ge, eigenes PrĂ€fix tr-, eigene Ansicht "training" (UI.app.registrieren("training", 
)).

Spiel.TRAINING = [ {id, titel, beschreibung, skill, geraet, art:"basis"|"stoerung"|"pruefung", minuten, geruest:true} 
 ];
Spiel.training.liste()          // -> [{
def, stand:{versucht, bestanden, sterne}, offen:boolean, grund}]
Spiel.training.starten(id)      // -> {ok, iid} | {ok:false, grund}     legt eine Instanz mit quelle "training" an
Spiel.training.stand()          // -> Spiel.st.training = {je:{[id]:{versucht,bestanden,bestes}}}
Spiel.training.abnehmen(iid, ergebnis)   // schreibt Stand + L.ueben, KEIN Euro/Ruf, KEIN Karrierefortschritt

Regeln: Training zahlt kein Geld und keinen Ruf (sonst wird es zur Geldquelle statt zum Üben), aber es zĂ€hlt fĂŒr den Lernmotor (L.ueben) und fĂŒr den Trainingsstand. Es erscheint nie im Postfach und nie in der Karriere-Wertung. Stufe meister sieht es nur als Liste ohne GerĂŒst.

§ 7 · Schreibrechte (damit sich niemand ĂŒberschreibt)

Ein Besitzer je Datei. Wer eine fremde Datei braucht, ruft ihre öffentliche FlÀche auf.

BausteinDateien (Eigentum)
Kern-Stufensystemsrc/spiel/stufensystem.js · src/ui/stufensystem.js
Terminal-Hilfesrc/daten/hilfen.js · src/spiel/hilfe.js (nur anfĂŒgen, s. u.) · src/ui/hilfe.js · src/stil/hilfe.css · src/ui/konsole.js
Leiste/Minisrc/spiel/mini.js · src/ui/leiste.js · src/ui/karriere.js · src/stil/leiste.css
Trainingsbereichsrc/spiel/training.js · src/ui/training.js · src/stil/training.css
Doku + Bau + Abnahmedocs/Architektur.md · docs/entwicklung/Design – Spielspaß 2.0.md · src/ui/app.js · AGENTS.md

src/spiel/hilfe.js gehört der bestehenden Hilfeleiter. Der Terminal-Baustein darf dort nur am Dateiende neue Funktionen anfĂŒgen (Spiel.hilfe.*), keine bestehende Zeile Ă€ndern. Das ist die einzige geteilte Datei — sie wird an genau einer Stelle angefasst.

bauen.py nimmt neue Dateien in src/daten, src/spiel, src/ui, src/stil automatisch auf (alphabetisch, mit Kopf-/Schlusslisten). Kein Eintrag nötig, keine ReihenfolgeÀnderung.

§ 8 · Was als „fertig" gilt (Abnahme, sechs Punkte)

  1. node tests/run.js ist ≄ 251/251 grĂŒn, python tools/ethos.py meldet GRÜN.
  2. python bauen.py lÀuft durch (Browser-Fassung), keine Ausnahme.
  3. Zu jedem Baustein gibt es eine neue Testdatei tests/spiel-<baustein>.test.js bzw. tests/cli-<baustein>.test.js nach der Art von tests/harness.js.
  4. Wirkung vor GrĂŒn: Der Baustein wird aus dem echten Weg aufgerufen (Terminal-Zeile, Leisten-Knopf, Trainingsansicht). Ein Test, der nur seinen eigenen Aufruf prĂŒft, gilt als nicht fertig.
  5. Die Stufen azubi und meister sind beide durchgespielt: azubi kommt ohne Syntaxkenntnis voran, meister sieht keine ungefragte Hilfe.
  6. docs/Architektur.md (Stand-Tabelle) und docs/entwicklung/Design – Spielspaß 2.0.md (neuer Abschnitt) zeigen den echten Zustand.

§ 9 · Offene Punkte (ehrlich, Stand 07.10.2026)