Aus #144 („Später“). Plattformen, durch die man von unten durchspringt und auf denen man von oben landet.
Befund
Zwei Wege bewegen Objekte gegen Collider, beide brauchen die Regel:
Move mit „Collide with solids“ → unsere Geometrie in Solids (#150/#151). Dort ist es einfach: Ein One-Way-Collider blockiert nur, wenn die Kontaktnormale in die erlaubte Richtung zeigt und der Mover vorher nicht schon in ihm steckte.
Dynamic Bodies in Rapier. Die JS-Version von Rapier 0.20 hat keinmodifySolverContacts (gibt es nur in Rust), sondern nur den Hook filterContactPair: pro Paar ganz an oder ganz aus, entschieden vor dem Step. Die Entscheidung muss dort aus Position und Geschwindigkeit fallen — geprüft, ob das ohne Ruckeln trägt, ist es nicht.
Für Tilemaps: One-Way pro Tile-Art, damit Plattform-Tiles keinen eigenen Collider brauchen.
Zu bauen
Am Collider: Schalter One-way + Richtung (Vorgabe: nach oben, d. h. blockiert nur von oben). Dreht mit dem Objekt.
Tile-Art: One-way als Option.
Solids: Regel wie oben; Move meldet Treffer nur, wenn blockiert wurde.
PhysicsSystem: filterContactPair mit derselben Regel, Zustand „steckt schon drin“ pro Paar merken, bis sie sich trennen.
„Durchfallen lassen“ (Drop-through, Taste runter): Node Ignore one-way für eine Dauer.
Tests: Sprung von unten durch, Landen oben, seitlich hineinlaufen, schneller Fall ohne Tunneln, Dynamic Body gleich wie Move, gegen beide Systeme.
Offen (mit Vorschlag)
Seitliches Hineinlaufen: Vorschlag: nicht blockieren (nur die Normale in Plattform-Richtung zählt), wie in Unity/Godot.
Toleranzwinkel für schräge One-Way-Plattformen: Vorschlag: 45°, als Feld später, falls nötig.
Rapier-Weg zuerst messen: Vorschlag: vor dem Bau ein kurzer Spike, ob filterContactPair bei 60 Hz sauber landet; wenn nicht, bekommen Dynamic Bodies One-Way erst später und der Inspector sagt das.
Aus #144 („Später“). Plattformen, durch die man von unten durchspringt und auf denen man von oben landet.
## Befund
- Zwei Wege bewegen Objekte gegen Collider, beide brauchen die Regel:
1. `Move` mit „Collide with solids“ → unsere Geometrie in `Solids` (#150/#151). Dort ist es einfach: Ein One-Way-Collider blockiert nur, wenn die Kontaktnormale in die erlaubte Richtung zeigt **und** der Mover vorher nicht schon in ihm steckte.
2. Dynamic Bodies in Rapier. Die JS-Version von Rapier 0.20 hat **kein** `modifySolverContacts` (gibt es nur in Rust), sondern nur den Hook `filterContactPair`: pro Paar ganz an oder ganz aus, entschieden vor dem Step. Die Entscheidung muss dort aus Position und Geschwindigkeit fallen — geprüft, ob das ohne Ruckeln trägt, ist es nicht.
- Für Tilemaps: One-Way pro Tile-Art, damit Plattform-Tiles keinen eigenen Collider brauchen.
## Zu bauen
- Am Collider: Schalter **One-way** + Richtung (Vorgabe: nach oben, d. h. blockiert nur von oben). Dreht mit dem Objekt.
- Tile-Art: One-way als Option.
- `Solids`: Regel wie oben; `Move` meldet Treffer nur, wenn blockiert wurde.
- `PhysicsSystem`: `filterContactPair` mit derselben Regel, Zustand „steckt schon drin“ pro Paar merken, bis sie sich trennen.
- „Durchfallen lassen“ (Drop-through, Taste runter): Node **Ignore one-way** für eine Dauer.
- Tests: Sprung von unten durch, Landen oben, seitlich hineinlaufen, schneller Fall ohne Tunneln, Dynamic Body gleich wie `Move`, gegen beide Systeme.
## Offen (mit Vorschlag)
1. **Seitliches Hineinlaufen:** Vorschlag: nicht blockieren (nur die Normale in Plattform-Richtung zählt), wie in Unity/Godot.
2. **Toleranzwinkel** für schräge One-Way-Plattformen: Vorschlag: 45°, als Feld später, falls nötig.
3. **Rapier-Weg zuerst messen:** Vorschlag: vor dem Bau ein kurzer Spike, ob `filterContactPair` bei 60 Hz sauber landet; wenn nicht, bekommen Dynamic Bodies One-Way erst später und der Inspector sagt das.
admin
added this to the Development project 2026-09-18 23:03:37 +02:00
folgendes issue anlegen, falls noch nicht passiert: One-Way-Platform, Toleranzwinkel für schräge One-Way-Plattformen als Feld (Default die jetzigen 45 grad)
folgendes issue anlegen, falls noch nicht passiert: One-Way-Platform, Toleranzwinkel für schräge One-Way-Plattformen als Feld (Default die jetzigen 45 grad)
Umgesetzt in 6a31f5e, zusammen mit #153 und #149. Die Vorschläge aus „Offen“ sind so übernommen, der Spike lief vorab.
Was gebaut ist
Collider: Schalter One-way und Blocks from (Above/Below/Left/Right). Die Seite dreht und spiegelt mit dem Objekt, der Scene-View zeichnet sie dick.
Tiles: Option One-way (from above). One-Way-Zellen verschmelzen nie mit festen Tiles zu einem Rechteck.
Regel: Blockiert wird nur ein Kontakt, dessen Normale höchstens 45° von der blockierenden Seite abweicht. Von unten und von der Seite geht es durch, was schon drinsteckt, fällt durch. Eine Funktion (landsOn) für Move, Raycast und Rapier.
Node Ignore one-way (Objekt, Sekunden): Durchfallen für eine Dauer.
Spike Rapier (gemessen bei 60 Hz)
Der Hook darf die Engine nicht anfassen: schon body.translation() darin wirft, der Fehler wird verschluckt und das Paar kollidiert mit gar nichts. Die Entscheidung fällt deshalb vor jedem Step, der Hook liest sie nur.
Landung: 1,9 px Einsinken, danach Ruhe bei 0,009 px. Von unten durch → landet oben. Seitlich → fährt durch. 2000 px/s → landet sauber, mit und ohne CCD.
Unterwegs behoben
Bei 2000 px/s steckt ein Body einen Step später 13 px in einer 8 px dünnen Plattform. Eine Landung hält jetzt, solange sich beide überlappen.
Ein schlafender Body fiel bei Ignore one-way nicht, er wird jetzt geweckt.
Altfehler: Im Play hatten alle Rapier-Collider einer Tilemap die Form ihrer letzten Zelle. Behoben, Regressionstest ist ohne Fix rot.
Tests
tests/core/one-way.test.ts, gegen beide Systeme (Move/Editor-Run und Rapier).
e2e-Modul 43 queries: Inspector-Schalter, Landen und Durchfallen mit Move, Dynamic Body von unten durch.
Lokal: npm run check → 109 Files, 1560 Tests, CHECK EXIT 0; GM_STEPS=39-43 → ALL PASSED – 99 checks. CI zu 6a31f5e lief beim Schreiben noch, die Summe 1073 ist gerechnet — Nachtrag folgt.
Folge-Issue
Der Toleranzwinkel als Feld (Punkt 2) steht in #159.
Umgesetzt in `6a31f5e`, zusammen mit #153 und #149. Die Vorschläge aus „Offen“ sind so übernommen, der Spike lief vorab.
## Was gebaut ist
- **Collider:** Schalter **One-way** und **Blocks from** (Above/Below/Left/Right). Die Seite dreht und spiegelt mit dem Objekt, der Scene-View zeichnet sie dick.
- **Tiles:** Option **One-way (from above)**. One-Way-Zellen verschmelzen nie mit festen Tiles zu einem Rechteck.
- **Regel:** Blockiert wird nur ein Kontakt, dessen Normale höchstens 45° von der blockierenden Seite abweicht. Von unten und von der Seite geht es durch, was schon drinsteckt, fällt durch. Eine Funktion (`landsOn`) für `Move`, Raycast und Rapier.
- **Node `Ignore one-way`** (Objekt, Sekunden): Durchfallen für eine Dauer.
## Spike Rapier (gemessen bei 60 Hz)
- Der Hook darf die Engine nicht anfassen: schon `body.translation()` darin wirft, der Fehler wird verschluckt und das Paar kollidiert mit gar nichts. Die Entscheidung fällt deshalb **vor** jedem Step, der Hook liest sie nur.
- Landung: 1,9 px Einsinken, danach Ruhe bei 0,009 px. Von unten durch → landet oben. Seitlich → fährt durch. 2000 px/s → landet sauber, mit und ohne CCD.
## Unterwegs behoben
- Bei 2000 px/s steckt ein Body einen Step später 13 px in einer 8 px dünnen Plattform. Eine Landung hält jetzt, solange sich beide überlappen.
- Ein schlafender Body fiel bei `Ignore one-way` nicht, er wird jetzt geweckt.
- **Altfehler:** Im Play hatten alle Rapier-Collider einer Tilemap die Form ihrer letzten Zelle. Behoben, Regressionstest ist ohne Fix rot.
## Tests
- `tests/core/one-way.test.ts`, gegen beide Systeme (Move/Editor-Run und Rapier).
- e2e-Modul 43 `queries`: Inspector-Schalter, Landen und Durchfallen mit `Move`, Dynamic Body von unten durch.
- Lokal: `npm run check` → 109 Files, 1560 Tests, `CHECK EXIT 0`; `GM_STEPS=39-43` → `ALL PASSED – 99 checks`. CI zu `6a31f5e` lief beim Schreiben noch, die Summe 1073 ist gerechnet — Nachtrag folgt.
## Folge-Issue
Der Toleranzwinkel als Feld (Punkt 2) steht in #159.
Nachtrag CI zu 6a31f5e: grün, selbst in den Job-Logs nachgelesen. Gate (Task 144): 109 Testdateien grün, CHECK EXIT 0. Suite (Task 145): ALL PASSED – 1073 checks – die Summe 1073 in README und Wiki ist damit gemessen. Smokes 24 / 19 / 21, alle grün.
**Nachtrag CI zu `6a31f5e`:** grün, selbst in den Job-Logs nachgelesen. Gate (Task 144): 109 Testdateien grün, `CHECK EXIT 0`. Suite (Task 145): `ALL PASSED – 1073 checks` – die Summe 1073 in README und Wiki ist damit gemessen. Smokes 24 / 19 / 21, alle grün.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Aus #144 („Später“). Plattformen, durch die man von unten durchspringt und auf denen man von oben landet.
Befund
Movemit „Collide with solids“ → unsere Geometrie inSolids(#150/#151). Dort ist es einfach: Ein One-Way-Collider blockiert nur, wenn die Kontaktnormale in die erlaubte Richtung zeigt und der Mover vorher nicht schon in ihm steckte.modifySolverContacts(gibt es nur in Rust), sondern nur den HookfilterContactPair: pro Paar ganz an oder ganz aus, entschieden vor dem Step. Die Entscheidung muss dort aus Position und Geschwindigkeit fallen — geprüft, ob das ohne Ruckeln trägt, ist es nicht.Zu bauen
Solids: Regel wie oben;Movemeldet Treffer nur, wenn blockiert wurde.PhysicsSystem:filterContactPairmit derselben Regel, Zustand „steckt schon drin“ pro Paar merken, bis sie sich trennen.Move, gegen beide Systeme.Offen (mit Vorschlag)
filterContactPairbei 60 Hz sauber landet; wenn nicht, bekommen Dynamic Bodies One-Way erst später und der Inspector sagt das.folgendes issue anlegen, falls noch nicht passiert: One-Way-Platform, Toleranzwinkel für schräge One-Way-Plattformen als Feld (Default die jetzigen 45 grad)
Umgesetzt in
6a31f5e, zusammen mit #153 und #149. Die Vorschläge aus „Offen“ sind so übernommen, der Spike lief vorab.Was gebaut ist
landsOn) fürMove, Raycast und Rapier.Ignore one-way(Objekt, Sekunden): Durchfallen für eine Dauer.Spike Rapier (gemessen bei 60 Hz)
body.translation()darin wirft, der Fehler wird verschluckt und das Paar kollidiert mit gar nichts. Die Entscheidung fällt deshalb vor jedem Step, der Hook liest sie nur.Unterwegs behoben
Ignore one-waynicht, er wird jetzt geweckt.Tests
tests/core/one-way.test.ts, gegen beide Systeme (Move/Editor-Run und Rapier).queries: Inspector-Schalter, Landen und Durchfallen mitMove, Dynamic Body von unten durch.npm run check→ 109 Files, 1560 Tests,CHECK EXIT 0;GM_STEPS=39-43→ALL PASSED – 99 checks. CI zu6a31f5elief beim Schreiben noch, die Summe 1073 ist gerechnet — Nachtrag folgt.Folge-Issue
Der Toleranzwinkel als Feld (Punkt 2) steht in #159.
Nachtrag CI zu
6a31f5e: grün, selbst in den Job-Logs nachgelesen. Gate (Task 144): 109 Testdateien grün,CHECK EXIT 0. Suite (Task 145):ALL PASSED – 1073 checks– die Summe 1073 in README und Wiki ist damit gemessen. Smokes 24 / 19 / 21, alle grün.