Sprung-Eingabepuffer wirkt nicht: 120 ms konfiguriert, real ≤ 1 Simulationsschritt (~8 ms) #4

Open
opened 2026-08-29 01:41:04 +02:00 by G1LL1 · 2 comments
G1LL1 commented 2026-08-29 01:41:04 +02:00 (Migrated from gitlab.g1ll1.com)

Komponente: INPUT (consume), GAME (playerCmd)
Betroffene Version: main @ 238ed66, index.html Zeilen 2086, 2544–2548

Beschreibung

AGENTS.md verlangt einen Sprung-Eingabepuffer von ca. 100–140 ms, damit ein Sprung kurz vor der
Landung noch annimmt. Gemessen wird der Puffer mit K.JUMP_BUFFER = 0.12 gesetzt, aber schon
nach dem ersten Simulationsschritt wieder verworfen:

{
  "specBufferMs": 120,
  "bufferRightAfterPress": 120,
  "bufferAfterEachFrame_ms": [0, 0, 0, 0, 0],
  "airborneAtPress": true,
  "jumpedAtTouchdown": false
}

Test: Sprung ausführen, in der Luft jump drücken, Landung abwarten → kein Puffer-Sprung.

Ursache

Zwei Stellen zusammen nehmen dem Puffer seine Wirkung:

// index.html:2081-2092  INPUT.consume()
if (state.jumpBuffer > 0) { c.jump = true; state.jumpBuffer = 0; }   // wird PRO Simulationsschritt gerufen

consume() läuft in der Fixzeitschleife (FIXED_TIMESTEP = 1/120). Der_next step, der die
Puffer-Schranke sieht, verwertet sie – unabhängig davon, ob die Figur überhaupt springen kann.

// index.html:2544-2548  GAME.playerCmd()
if (c.jump) {
  if (body.grounded || body.coyote > 0) out.jump = true;
  else out.grab = true;          // in der Luft: Eingabe wird zum Greifversuch UMGEWEGET und ist verbraucht
}

Eine in der Luft gedrückte Sprungtaste wird also zum (evtl. erfolglosen) Greifversuch
degradiert und ist danach weg. Der in tickTimers() herunterzählende Puffer überlebt damit
höchstens einen einzigen Fixschritt.

Reproduktion

Playwright über window.PULSE:

// in der Luft drücken
PULSE.press('jump');                      // Sprung 1
PULSE.update(1/120);                      // airborne
PULSE.press('jump');                      // Eingabe ~1 Frame nach dem Absprung, soll puffern
const b0 = INPUT.state.jumpBuffer;        // 0.12
PULSE.update(1/120);                      // -> INPUT.state.jumpBuffer === 0
// danach bis zur Landung weiterschalten: kein Sprung bei touchdown

Auswirkung

  • Kein Eingabeverzeihen bei der Landung nach großen Sprüngen / nach dem Loslassen eines Schwungs –
    der häufigsten Timing-Situation im Spiel.
  • Autogriff/„Sprung in der Luft = Haken greifen“ überlagert die Erwartung „Springen puffern“.
  • Abweichung von einer explizit formulierten Vorgabe aus AGENTS.md.

Lösungsvorschlag

  1. consume() soll die jump-Kante nur verbrauchen, wenn sie auch ausführbar ist; sonst der
    Puffer weiterlaufen lassen:
function consume(canJump) {
  const c = { jumpHeld: state.jumpHeld, /* ... */ };
  if (state.jumpBuffer > 0) {
    if (canJump) { c.jump = true; state.jumpBuffer = 0; }
    else if (!hooksAvailable) { /* Puffer verfallen lassen oder für Hook nutzen */ }
  }
  ...
}
  1. Alternativ explizit zwei Kanäle führen (jumpBuffer und grabBuffer) und in der Luft zuerst
    grabBuffer anbieten, jumpBuffer bis zur Landung laufen lassen.
  2. Regressionstest: Eingabe 20/40/70/100 ms vor touchdown → Sprung erfolgt bei Landung;
    Eingabe 200 ms vorher → verfällt.

Dokumentiert in gitlab-issues/04-sprung-eingabepuffer-wirkt-nicht.md (Commit 238ed66). Alle Befunde ausgeführt und gemessen; Repro-Schritte im Text.

**Komponente:** INPUT (`consume`), GAME (`playerCmd`) **Betroffene Version:** `main` @ `238ed66`, `index.html` Zeilen 2086, 2544–2548 ## Beschreibung AGENTS.md verlangt einen Sprung-Eingabepuffer von ca. 100–140 ms, damit ein Sprung kurz vor der Landung noch annimmt. Gemessen wird der Puffer mit `K.JUMP_BUFFER = 0.12` gesetzt, aber schon nach dem ersten Simulationsschritt wieder verworfen: ```json { "specBufferMs": 120, "bufferRightAfterPress": 120, "bufferAfterEachFrame_ms": [0, 0, 0, 0, 0], "airborneAtPress": true, "jumpedAtTouchdown": false } ``` Test: Sprung ausführen, in der Luft `jump` drücken, Landung abwarten → **kein** Puffer-Sprung. ## Ursache Zwei Stellen zusammen nehmen dem Puffer seine Wirkung: ```js // index.html:2081-2092 INPUT.consume() if (state.jumpBuffer > 0) { c.jump = true; state.jumpBuffer = 0; } // wird PRO Simulationsschritt gerufen ``` `consume()` läuft in der Fixzeitschleife (`FIXED_TIMESTEP = 1/120`). Der_next step, der die Puffer-Schranke sieht, verwertet sie – unabhängig davon, ob die Figur überhaupt springen kann. ```js // index.html:2544-2548 GAME.playerCmd() if (c.jump) { if (body.grounded || body.coyote > 0) out.jump = true; else out.grab = true; // in der Luft: Eingabe wird zum Greifversuch UMGEWEGET und ist verbraucht } ``` Eine in der Luft gedrückte Sprungtaste wird also zum (evtl. erfolglosen) Greifversuch degradiert und ist danach weg. Der in `tickTimers()` herunterzählende Puffer überlebt damit höchstens einen einzigen Fixschritt. ## Reproduktion Playwright über `window.PULSE`: ```js // in der Luft drücken PULSE.press('jump'); // Sprung 1 PULSE.update(1/120); // airborne PULSE.press('jump'); // Eingabe ~1 Frame nach dem Absprung, soll puffern const b0 = INPUT.state.jumpBuffer; // 0.12 PULSE.update(1/120); // -> INPUT.state.jumpBuffer === 0 // danach bis zur Landung weiterschalten: kein Sprung bei touchdown ``` ## Auswirkung * Kein Eingabeverzeihen bei der Landung nach großen Sprüngen / nach dem Loslassen eines Schwungs – der häufigsten Timing-Situation im Spiel. * Autogriff/„Sprung in der Luft = Haken greifen“ überlagert die Erwartung „Springen puffern“. * Abweichung von einer explizit formulierten Vorgabe aus AGENTS.md. ## Lösungsvorschlag 1. `consume()` soll die jump-Kante **nur verbrauchen, wenn sie auch ausführbar ist**; sonst der Puffer weiterlaufen lassen: ```js function consume(canJump) { const c = { jumpHeld: state.jumpHeld, /* ... */ }; if (state.jumpBuffer > 0) { if (canJump) { c.jump = true; state.jumpBuffer = 0; } else if (!hooksAvailable) { /* Puffer verfallen lassen oder für Hook nutzen */ } } ... } ``` 2. Alternativ explizit zwei Kanäle führen (`jumpBuffer` und `grabBuffer`) und in der Luft zuerst `grabBuffer` anbieten, `jumpBuffer` bis zur Landung laufen lassen. 3. Regressionstest: Eingabe 20/40/70/100 ms vor touchdown → Sprung erfolgt bei Landung; Eingabe 200 ms vorher → verfällt. --- *Dokumentiert in `gitlab-issues/04-sprung-eingabepuffer-wirkt-nicht.md` (Commit `238ed66`). Alle Befunde ausgeführt und gemessen; Repro-Schritte im Text.*
G1LL1 commented 2026-08-29 01:45:24 +02:00 (Migrated from gitlab.g1ll1.com)

changed the description

changed the description
G1LL1 commented 2026-08-29 01:48:08 +02:00 (Migrated from gitlab.g1ll1.com)

changed the description

changed the description
Sign in to join this conversation.
No description provided.