Describe references into nested placements and on delete (#285, #286)

- Behaviors: a container object can pick content of a container
  placed inside it, the reference follows a pasted or wrapped
  placement, and deleting an asset clears references to its objects.
- Containers: how a reference is spelled in a template and in its
  placements, and that DeleteAssetCommand clears references too.
- Development: e2e total 1609.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-01 07:28:57 +02:00
1 parent 06fd1ec50c
commit 12a2b1639d
3 files changed
+24 -4

No files matched your search

+10 -2
@@ -79,16 +79,24 @@ playing use the same two words.
another selection, undo, redo or Play end it without writing. While it runs the view does
nothing else (no dragging, marquee, brush, handles or menu); panning and zooming still work.
- **Inside a container** an object only gets the objects of the same container to choose from,
named by their template id. Every placement of the container then reaches its own copy.
named as the container's own tab names them. That includes the content of a container placed
inside it (#285). Every placement of the container then reaches its own copy, nested content
included.
- **The reference follows the object:** removing it empties the reference in the same undo step,
copying and pasting several objects points a reference among them at the copy (one out of them
stays), *Create container* and *Unpack* carry it along.
stays), *Create container* and *Unpack* carry it along. A reference to the content of a placed
container follows the placement the same way: pasted together, it points into the copy, and
made into a container together, it points into the placement inside the new container.
- **Removing an object from a container template** (#269) empties every reference to it as well,
in the same undo step: in the template, in each placement of the container in every scene and
every other container (nested ones included), and on objects outside a placement that name its
copy. The row then says `None`. A placement that now holds the same value as its template
follows the template again. If the template has no value of its own there, the placement keeps
`None` as its own value, as if picked by hand, and *Reset* hands it back to the template.
- **Deleting an asset** (#286) does the same for every object it takes along: its placements in
scenes and container templates and everything parented below them. For a container asset that
includes the content of its placements. One undo brings the asset, the objects and the
references back.
- An object that is gone reads as `(null)`, and the row shows `(missing)`. That is left for
references that were already dead before #269: they disappear the next time the row is set.
+13 -1
@@ -47,7 +47,19 @@ resolved ids) and empties each object reference that named an object shown befor
with `referenceCandidates`, just as the running game does, so the same rule covers the template, a
placement's edits in any scene or container, nested placements and full derived ids on objects
outside. An emptied edit that now equals its base is dropped like any other. All of it goes through
the command's `Recorder`, so one undo brings every reference back.
the command's `Recorder`, so one undo brings every reference back. `DeleteAssetCommand` does the
same around its cascade (#286), so deleting an asset empties the references to every object it
takes along.
A reference is stored as the holder that holds it shows the object (#285). In a container D, the
content x of a placement q nested in D shows as `q~x`, and that is what a pick in D's tab stores.
In a placement r of D the same object is `r~q/x`: the first `~` of the reference becomes a `/`
(`pathOfId` in `core/model/instance.ts`) before the scope of the placement goes in front. The
inspector's choices on a placement go the other way (`idOfPath`), so the template and its
placements spell the same object the same way. Before #285 the lookup tried `r~q~x`, and such a
reference was dead from the start. `renamedReference` lets a reference to `q~x` follow when q is
renamed: by *Create container* (to `q'~x` inside the new template, to `c~q'/x` from outside) and by
pasting q together with the object holding the reference.
Two places do spell the content out. **Unpack** does it on purpose — the objects become ordinary
ones and stop following. And **play mode bakes** every placed container into stored objects, in
+1 -1
@@ -18,7 +18,7 @@ php tests/php/accounts.test.php # the API's accoun
# has and the web server's container has not (SKIP there)
php tests/php/snapshots.test.php # the snapshot store (#231), the same way
php tests/php/releases.test.php # the release store (#266), the same way
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1607 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1609 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result