Aus #258 („Deleting a template object in the container editor does not clean up references in other scenes.“, dort unter Not done).
Befund
Seit #258 zeigt eine Object-Variable (auch ein Object-Feld oder Object-Item) auf ein Objekt derselben Szene, gespeichert als {"$object": "<id>"}. Inhalt eines platzierten Containers bekommt nur Objekte desselben Containers zur Wahl. Die Wahl steht in den instanceEdits der Platzierung, also in der Szene, nicht im Template.
RemoveSceneObjectsCommand (src/core/commands/sceneObjectCommands.ts:119) leert beim Löschen nur die Verweise im selben Holder: swapReferences(holder.objects, …) in Zeile 124.
Löscht man im Container-Tab ein Template-Objekt, bleiben die Verweise darauf in den instanceEdits jeder Platzierung stehen, in allen Szenen und in anderen Container-Templates.
Folge: Der Inspector der Platzierung zeigt (missing), im Spiel liest sich der Wert als null, und der tote Verweis bleibt in der Projektdatei. In der eigenen Szene fällt derselbe Verweis dagegen im selben Undo-Schritt weg, wie in #258 vereinbart.
Zu bauen (Vorschlag)
Beim Löschen in einem Container-Template zusätzlich alle Platzierungen dieses Containers im Projekt durchgehen (Szenen und andere Templates, auch verschachtelt) und dort die Verweise auf die gelöschten Ids leeren. Das läuft über denselben Recorder, damit ein Undo alles zurückbringt.
Die Suche nach den Platzierungen als reine Funktion neben swapReferences in src/core/model/objectRefs.ts.
Tests: Unit mit einem Container, der in zwei Szenen platziert ist und dort je einen Verweis trägt. Löschen leert beide, Undo stellt beide wieder her. e2e im Container-Tab (Modul 57 baut die Verweise schon auf): Template-Objekt löschen, danach zeigt die Platzierung None statt (missing).
Offen (mit Vorschlag)
Verweise, die schon tot in Projekten stehen? Vorschlag: keine Migration. Sie lesen sich weiter als (missing) und verschwinden beim nächsten Setzen.
Aus #258 („Deleting a template object in the container editor does not clean up references in other scenes.“, dort unter *Not done*).
## Befund
- Seit #258 zeigt eine Object-Variable (auch ein Object-Feld oder Object-Item) auf ein Objekt derselben Szene, gespeichert als `{"$object": "<id>"}`. Inhalt eines platzierten Containers bekommt nur Objekte desselben Containers zur Wahl. Die Wahl steht in den `instanceEdits` der Platzierung, also in der Szene, nicht im Template.
- `RemoveSceneObjectsCommand` (`src/core/commands/sceneObjectCommands.ts:119`) leert beim Löschen nur die Verweise im selben Holder: `swapReferences(holder.objects, …)` in Zeile 124.
- Löscht man im Container-Tab ein Template-Objekt, bleiben die Verweise darauf in den `instanceEdits` jeder Platzierung stehen, in allen Szenen und in anderen Container-Templates.
- Folge: Der Inspector der Platzierung zeigt `(missing)`, im Spiel liest sich der Wert als `null`, und der tote Verweis bleibt in der Projektdatei. In der eigenen Szene fällt derselbe Verweis dagegen im selben Undo-Schritt weg, wie in #258 vereinbart.
## Zu bauen (Vorschlag)
- Beim Löschen in einem Container-Template zusätzlich alle Platzierungen dieses Containers im Projekt durchgehen (Szenen und andere Templates, auch verschachtelt) und dort die Verweise auf die gelöschten Ids leeren. Das läuft über denselben `Recorder`, damit ein Undo alles zurückbringt.
- Die Suche nach den Platzierungen als reine Funktion neben `swapReferences` in `src/core/model/objectRefs.ts`.
- Tests: Unit mit einem Container, der in zwei Szenen platziert ist und dort je einen Verweis trägt. Löschen leert beide, Undo stellt beide wieder her. e2e im Container-Tab (Modul 57 baut die Verweise schon auf): Template-Objekt löschen, danach zeigt die Platzierung `None` statt `(missing)`.
## Offen (mit Vorschlag)
1. **Verweise, die schon tot in Projekten stehen?** Vorschlag: keine Migration. Sie lesen sich weiter als `(missing)` und verschwinden beim nächsten Setzen.
meleki
added the new label 2026-09-29 18:26:29 +02:00
Done in 214218d, wiki 06fd1ec (Behaviors, Containers, Development).
What changes
Deleting a template object in a container tab now clears every reference to it, in the same undo step:
in the template itself (as before)
in the instanceEdits of every placement, in all scenes and in other container templates, nested ones included
on objects outside a placement that name its copy by full id (p~crate)
The row then shows None instead of (missing). One undo brings all references back.
References that were already dead in saved projects stay untouched, as agreed. They go away the next time the value is set.
Different from the proposal
Instead of searching for placements, the command compares which objects every holder shows before and after the delete (shownObjectIds and dropReferencesToGone in src/core/model/objectRefs.ts). A reference is resolved from its own place with referenceCandidates, the same way the runtime does. One rule covers all cases, nested placements too, and it also applies when a whole container placement is deleted in a scene.
A cleared instance edit is dropped when it now says the same as the template, so the placement follows the template again. That only happens when the template has its own value there. It is the same rule as in the setter and in deviatesFromTemplate, which compare overrides on purpose, not effective values.
When the template has no own value, a marked None stays, yellow and with Reset, just as if None had been picked by hand. Reset hands the row back to the template.
When the template points somewhere else, the placement stays at None. It does not jump silently to the template's value.
Tests
unit object-references (melektaus-atx) 17 passed (13 + 4)
gate (melektaus-atx) 198 files, 2873 tests, CHECK EXIT 0 (2869 + 4)
e2e 1-17,57 ALL PASSED - 564 checks (57 has 13, +1 for 57h)
57h deletes the crate in the container tab with the real Delete key. Before, the row shows Crate 57. After, it shows None without (missing), and undo brings the reference back.
Counter-checks work, each bent on its own in a container copy:
Bent
Failing tests
raw ids only
3
scenes skipped
5
no undo
4
clear everything named
3
edit not cleaned up
1
The browser counter-check works too: 57h then fails with exactly the picture from this issue, (missing) and the reference still in place.
Screenshot checked: under "Box 57" only Aim 57 is left, target shows None.
The e2e total of 1607 is computed (1606 + 1). CI is still switched off, so there is no run for 214218d.
Found on the way, not fixed here
#285: a reference from a container into a nested placement is stored as q~<id>, but the copy is named r~q/<id> in every placement. That reference is dead from the start.
#286: Delete asset removes placed objects by cascade but does not clear references to them.
Done in `214218d`, wiki `06fd1ec` (*Behaviors*, *Containers*, *Development*).
**What changes**
- Deleting a template object in a container tab now clears every reference to it, in the same undo step:
- in the template itself (as before)
- in the `instanceEdits` of every placement, in all scenes and in other container templates, nested ones included
- on objects outside a placement that name its copy by full id (`p~crate`)
- The row then shows **None** instead of `(missing)`. One undo brings all references back.
- References that were already dead in saved projects stay untouched, as agreed. They go away the next time the value is set.
**Different from the proposal**
- Instead of searching for placements, the command compares which objects every holder shows before and after the delete (`shownObjectIds` and `dropReferencesToGone` in `src/core/model/objectRefs.ts`). A reference is resolved from its own place with `referenceCandidates`, the same way the runtime does. One rule covers all cases, nested placements too, and it also applies when a whole container placement is deleted in a scene.
- A cleared instance edit is dropped when it now says the same as the template, so the placement follows the template again. That only happens when the template has its own value there. It is the same rule as in the setter and in `deviatesFromTemplate`, which compare overrides on purpose, not effective values.
- **When the template has no own value, a marked None stays**, yellow and with Reset, just as if None had been picked by hand. Reset hands the row back to the template.
- When the template points somewhere else, the placement stays at None. It does not jump silently to the template's value.
**Tests**
```
unit object-references (melektaus-atx) 17 passed (13 + 4)
gate (melektaus-atx) 198 files, 2873 tests, CHECK EXIT 0 (2869 + 4)
e2e 1-17,57 ALL PASSED - 564 checks (57 has 13, +1 for 57h)
```
- **57h** deletes the crate in the container tab with the real Delete key. Before, the row shows `Crate 57`. After, it shows `None` without `(missing)`, and undo brings the reference back.
- Counter-checks work, each bent on its own in a container copy:
| Bent | Failing tests |
|---|---|
| raw ids only | 3 |
| scenes skipped | 5 |
| no undo | 4 |
| clear everything named | 3 |
| edit not cleaned up | 1 |
- The browser counter-check works too: 57h then fails with exactly the picture from this issue, `(missing)` and the reference still in place.
- Screenshot checked: under "Box 57" only Aim 57 is left, *target* shows None.
- The e2e total of 1607 is computed (1606 + 1). CI is still switched off, so there is no run for `214218d`.
**Found on the way, not fixed here**
- #285: a reference from a container into a nested placement is stored as `q~<id>`, but the copy is named `r~q/<id>` in every placement. That reference is dead from the start.
- #286: *Delete asset* removes placed objects by cascade but does not clear references to them.
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 #258 („Deleting a template object in the container editor does not clean up references in other scenes.“, dort unter Not done).
Befund
{"$object": "<id>"}. Inhalt eines platzierten Containers bekommt nur Objekte desselben Containers zur Wahl. Die Wahl steht in deninstanceEditsder Platzierung, also in der Szene, nicht im Template.RemoveSceneObjectsCommand(src/core/commands/sceneObjectCommands.ts:119) leert beim Löschen nur die Verweise im selben Holder:swapReferences(holder.objects, …)in Zeile 124.instanceEditsjeder Platzierung stehen, in allen Szenen und in anderen Container-Templates.(missing), im Spiel liest sich der Wert alsnull, und der tote Verweis bleibt in der Projektdatei. In der eigenen Szene fällt derselbe Verweis dagegen im selben Undo-Schritt weg, wie in #258 vereinbart.Zu bauen (Vorschlag)
Recorder, damit ein Undo alles zurückbringt.swapReferencesinsrc/core/model/objectRefs.ts.Nonestatt(missing).Offen (mit Vorschlag)
(missing)und verschwinden beim nächsten Setzen.vorschlag passt
Done in
214218d, wiki06fd1ec(Behaviors, Containers, Development).What changes
instanceEditsof every placement, in all scenes and in other container templates, nested ones includedp~crate)(missing). One undo brings all references back.Different from the proposal
shownObjectIdsanddropReferencesToGoneinsrc/core/model/objectRefs.ts). A reference is resolved from its own place withreferenceCandidates, the same way the runtime does. One rule covers all cases, nested placements too, and it also applies when a whole container placement is deleted in a scene.deviatesFromTemplate, which compare overrides on purpose, not effective values.Tests
57h deletes the crate in the container tab with the real Delete key. Before, the row shows
Crate 57. After, it showsNonewithout(missing), and undo brings the reference back.Counter-checks work, each bent on its own in a container copy:
The browser counter-check works too: 57h then fails with exactly the picture from this issue,
(missing)and the reference still in place.Screenshot checked: under "Box 57" only Aim 57 is left, target shows None.
The e2e total of 1607 is computed (1606 + 1). CI is still switched off, so there is no run for
214218d.Found on the way, not fixed here
q~<id>, but the copy is namedr~q/<id>in every placement. That reference is dead from the start.