Sprung-Physik: Abstiegsphase existiert nicht – Figur teleportiert vom Scheitelpunkt auf den Boden #2
Labels
No labels
accessibility
bug
cleanup
consistency
crash
critical
game-feel
gameplay
high
input
level-generation
low
maintainability
medium
pause
physics
responsive
security
spec-gap
ui
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gilli/pulse-sprint#2
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Komponente: CORE (
integrateFree)Betroffene Version:
main@238ed66,index.htmlZeile 685Beschreibung
Jeder Sprung endet abrupt im Scheitelpunkt: Die Figur steigt bis zum Apex und ist einen Frame
später wieder am Boden – auch bei 229 px Höhe. Es gibt keine Fallphase.
Bei 25 Sprüngen auf flachem Boden über den echten
PULSE.update()-Pfad gemessen:jumpDistance= 278 pxFrame-Exakt-Trace (Schrittweite 1/120 s):
Ursache
Die Landungsbedingung in
integrateFree()ist invertiert:(b.y + offPrev) <= surf.y + EDGE_LIFTbedeutet „Fuß über der Oberfläche“ – das ist derkollisionsfreie Fall. Sobald
vy >= 0wird (genau im Apex), ist die Bedingung wahr und dieFigur wird auf
surf.y - offgesnappt. Landen würde>=(Fuß erreicht/unterschreitet dieOberfläche) plus einen Vor-Frame-Abgleich gegen „Durchsacken“ verlangen.
Der
EDGE_LIFT-Gedanke aus AGENTS.md („Fuß-Hitbox beim Übergang über eine Kante um ca. 4–6 pxanheben, damit die Figur nicht an der Kantenhöhe hängen bleibt“) ist dadurch ebenfalls
unwirksam.
Reproduktion
Playwright über
window.PULSE(Test-Hook im File, Zeile 2966):Zähltest über 25 Sprünge:
airborneFramesGoingUp: 1350, airborneFramesComingDown: 0, apexTeleportEvents: 25, maxTeleportPxPerFrame: 229.Auswirkung
jumpDistance(v)(Zeile 761) rechnet mit dervollständigen Parabel (
2·|JUMP_VELOCITY|/GRAVITY→ 0,75 s). Die Generierung vonGrubenbreiten (
maxGapJumpable = 0,72 × jumpDistance,PITbis 0,92 × maxGapJumpable) unddie Dokumentation beruhen auf einem Wert, den die Physik nicht liefert.
über der jeweiligen Oberfläche ausgelöst wird, kann die Figur nicht von oben auf einer
tieferen Plattform zubewegt werden; stattdessen Teleport auf diejenige Fläche, die unter
b.xliegt.
Absturz den HALTE-Bonus ohnehin sofort beendet.
10.000-Muster-Tests diesen Fehler nicht – die Generierung bleibt spielbar, aber alles
dokumentierte/verifizierte Sprungverhalten weicht von den zentralen Konstanten ab.
Lösungsvorschlag
Landung auf „Fuß erreicht Oberfläche von oben“ umstellen, mit Vor-Frame-Fenster gegen
Durchsacken und
EDGE_LIFTals Kanten-Toleranz:Danach bitte prüfen/ergänzen:
jumpDistance(v)stimmen mit der Messung überein (Regressionstest).PIT_PLATFORM/PIT_DOUBLEaus größerer Höhe.PIT-Breiten ggf. neu justieren, wenn die reale Sprungweite wieder steigt.Dokumentiert in
gitlab-issues/02-sprung-keine-abstiegsphase.md(Commit238ed66). Alle Befunde ausgeführt und gemessen; Repro-Schritte im Text.mentioned in issue #12
changed the description
changed the description
mentioned in commit
174aeb72a1Behoben in
174aeb7(main).Umsetzung
Landung in
integrateFree()heißt jetzt „Fuß erreicht die Oberfläche von oben“ mitVor-Frame-Fenster gegen Durchsacken und
EDGE_LIFTals Kanten-Toleranz:b.pywird instepBody()bereits vor der Integration gesetzt, deshalb ist der Vergleichechter Vor-/Nachrahmen.
ev.landedfeuert damit außerdem erst bei tatsächlicher Landung(zuvor im Scheitelpunkt – das hatte Staub, Landeton und Schwung-Wertung an den falschen Moment
gehängt).
Messung danach (Playwright über
window.PULSE, 1/120 s)jumpDistance= 300 px)Die reale Sprungweite liegt damit über der Formel aus AGENTS.md, weil
JUMP_HOLD_BOOSTdie Fallzeit verlängert; die Generierung rechnet weiterhin mit der Formel und bleibt dadurch
leicht konservativ. Nachjustieren war nicht nötig:
PIT/PIT_PLATFORM/PIT_DOUBLE/PIT_HOOKwerden weiterhin verworfen bzw. über die Fallback-Kette ersetzt, wenn sie nicht passen
(0 erzwungene
SAFE-Fallbacks bei 10 000 Mustern).Der Solver war vorher selbstkonsistent und konnte den Fehler nicht fangen – deshalb wurde der
Test um eine Schrittweiten-Band-Prüfung ergänzt (1/100 … 1/144, also auch der reale
FIXED_TIMESTEP1/120 nebenSIM_DT1/110): 96 Muster, 0 Fehlschläge. Damit ist Lösbarkeitnicht mehr an eine bestimmte Simulationsschrittweite gekettet.
Tests
node .pi/tests/issue2.mjs– 20 Prüfungen: Abstiegsphase, Parabel-Symmetrie, kein Teleport,Luftzeit, Sprungweite vs.
jumpDistance, exakte Landung ohne Einsacken, kurzer Sprung durchfrühes Loslassen, Landung auf Plattform aus größerer Höhe, Coyote Time an der Grubenkante,
Grube überspringen, Grubensturz genau einmal
fell, kein NaN, 30 fps ohne Durchsacken.node .pi/tests/soak.mjs– 5 Minuten Autopilot-Spielzeit (18,4 km, bis Sektor 41/Endlos)ohne Tod, keine NaN, maximal 31 lebende Objekte.
requestAnimationFrame-Loop (.pi/tests/browser_flow.py) bei1366×768, 320×640 und 844×390: je Sprung Auf- und Abstieg, kein Teleport, keine Konsolenfehler.
mentioned in issue #6