Sort a child with its parent instead of across the whole scene #232

Closed
opened 2026-09-25 22:18:52 +02:00 by meleki · 1 comment
Owner

Problem

Z is global today. A child's world Z is the parent's Z plus its own, and drawSlots() sorts every object of the scene in one flat list. A child with Z -1 (a weapon that should pass behind the player's head) therefore drops behind everything on Z 0: other characters, and the rows of a tilemap layer sorted by Y. It also leaves the Y sorting of its parent, because that only works within one Z step.

Decision (user, 2026-09-25)

  • New switch "Sort with parent" on the child object (property sortWithParent, boolean).
  • Existing objects stay off, so old projects draw exactly as before. Newly created assets start with it on.
  • With the switch on, the child is drawn in its parent's slot:
    • Against the rest of the scene only the parent counts, with its Z and, on a Z sorted by Y, its feet.
    • The child's own Z only orders it against the parent and its siblings: below 0 behind the parent, 0 and above in front of it. Ties keep the hierarchy order.
    • This chains: a grandchild with the switch on sorts with the topmost object of the chain.

Scope

  • Sprite, text and particle source. A tilemap has no single place in the draw order, so it can neither join nor lead such a group.
  • A parent that is not drawn itself (container, behavior, camera, collider) has no slot to join; the switch does nothing there.
  • Editor view, running game and picking use the same order (drawSlots).
## Problem Z is global today. A child's world Z is the parent's Z plus its own, and `drawSlots()` sorts every object of the scene in one flat list. A child with Z -1 (a weapon that should pass behind the player's head) therefore drops behind **everything** on Z 0: other characters, and the rows of a tilemap layer sorted by Y. It also leaves the Y sorting of its parent, because that only works within one Z step. ## Decision (user, 2026-09-25) - New switch **"Sort with parent"** on the child object (property `sortWithParent`, boolean). - **Existing objects stay off**, so old projects draw exactly as before. **Newly created assets start with it on.** - With the switch on, the child is drawn in its parent's slot: - Against the rest of the scene only the parent counts, with its Z and, on a Z sorted by Y, its feet. - The child's own Z only orders it against the parent and its siblings: below 0 behind the parent, 0 and above in front of it. Ties keep the hierarchy order. - This chains: a grandchild with the switch on sorts with the topmost object of the chain. ## Scope - Sprite, text and particle source. A tilemap has no single place in the draw order, so it can neither join nor lead such a group. - A parent that is not drawn itself (container, behavior, camera, collider) has no slot to join; the switch does nothing there. - Editor view, running game and picking use the same order (`drawSlots`).
Author
Owner

Umgesetzt in 8b44f97 (Wiki 604a2e2), Variante A aus der Rückfrage.

Verhalten

  • Neuer Schalter Sort with parent an Sprite, Text und Partikelquelle, direkt unter Z.
  • Ist er an, wird das Kind an der Stelle seines Parents gezeichnet. Gegenüber dem Rest der Szene zählen nur Z (und bei Sort by Y die Füße) des Parents. Die Z des Kindes ordnet es nur gegenüber Parent und Geschwistern: unter 0 dahinter, ab 0 davor.
  • Gilt über mehrere Ebenen: Ein Enkel mit Schalter hängt am obersten Objekt der Kette.
  • Neu angelegte Assets starten mit an, bestehende lesen sich als aus. Alte Projekte zeichnen unverändert.
  • Normale Property: am Asset gesetzt, pro Objekt überschreibbar.
  • Wirkungslos unter einem Parent, der nicht gezeichnet wird (Container, Behavior, Kamera, Collider), und unter einer Tilemap.

Umsetzung

  • src/viewport/drawOrder.ts: parentGroups() gibt nur dem obersten Objekt einer Kette einen Platz, die Kinder werden dort eingefügt. Editor, Spiel und Picking nutzen dieselbe Funktion.
  • Schemazeilen haben neben default jetzt initial (Startwert eines neuen Assets). Gold-Markierung und Reset richten sich danach, sonst wäre jedes neue Sprite als geändert markiert.

Tests

  • tests/viewport/sort-with-parent.test.ts: 10 neue Tests. 8 bestehende Tests mit festen Zeilenlisten um die neue Zeile ergänzt.
  • e2e 5b-ii: Schalter per Klick, Zeichenreihenfolge, Undo.
  • Gate: 166 Dateien, 2426 Tests, CHECK EXIT 0. e2e 5: 13 Checks grün.
  • 5 Gegenproben greifen (Schalter ignoriert: 7 fallen, Kinder nicht nach Z sortiert: 6, keine Kette: 1, initial ignoriert: 9, Zeile fehlt im Inspector: e2e fällt).
  • Check-Summe 1398, gerechnet.
Umgesetzt in `8b44f97` (Wiki `604a2e2`), Variante A aus der Rückfrage. ## Verhalten - Neuer Schalter **Sort with parent** an Sprite, Text und Partikelquelle, direkt unter Z. - Ist er an, wird das Kind an der Stelle seines Parents gezeichnet. Gegenüber dem Rest der Szene zählen nur Z (und bei Sort by Y die Füße) des Parents. Die Z des Kindes ordnet es nur gegenüber Parent und Geschwistern: unter 0 dahinter, ab 0 davor. - Gilt über mehrere Ebenen: Ein Enkel mit Schalter hängt am obersten Objekt der Kette. - Neu angelegte Assets starten mit an, bestehende lesen sich als aus. Alte Projekte zeichnen unverändert. - Normale Property: am Asset gesetzt, pro Objekt überschreibbar. - Wirkungslos unter einem Parent, der nicht gezeichnet wird (Container, Behavior, Kamera, Collider), und unter einer Tilemap. ## Umsetzung - `src/viewport/drawOrder.ts`: `parentGroups()` gibt nur dem obersten Objekt einer Kette einen Platz, die Kinder werden dort eingefügt. Editor, Spiel und Picking nutzen dieselbe Funktion. - Schemazeilen haben neben `default` jetzt `initial` (Startwert eines neuen Assets). Gold-Markierung und Reset richten sich danach, sonst wäre jedes neue Sprite als geändert markiert. ## Tests - `tests/viewport/sort-with-parent.test.ts`: 10 neue Tests. 8 bestehende Tests mit festen Zeilenlisten um die neue Zeile ergänzt. - e2e 5b-ii: Schalter per Klick, Zeichenreihenfolge, Undo. - Gate: 166 Dateien, 2426 Tests, `CHECK EXIT 0`. e2e 5: 13 Checks grün. - 5 Gegenproben greifen (Schalter ignoriert: 7 fallen, Kinder nicht nach Z sortiert: 6, keine Kette: 1, `initial` ignoriert: 9, Zeile fehlt im Inspector: e2e fällt). - Check-Summe 1398, gerechnet.
admin added this to the Development project 2026-09-27 11:28:31 +02:00
admin moved this to Done in Development on 2026-09-27 11:28:56 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#232