Typisierte Listen: Variable schreiben und List-Node prüfen den Typ nicht #271

Closed
opened 2026-09-29 18:26:30 +02:00 by meleki · 2 comments
Owner

Aus #254 („Not done: writing a variable does not check the type, the List node offers no type.“) und deiner Antwort dort: „typed lists dürfen nur den passenden typed structs erhalten“.

Befund

  • Seit #254 prüfen Add item und Set item mit gesetztem Type, ob ein Wert genau die Felder des Struct-Assets hat. Alles andere lassen sie weg und melden es in der Konsole (src/core/graph/nodes/data/AddItem.ts:20, fitsType in SetItem.ts).
  • Der Variables-Node auf Set schreibt dagegen jeden Wert ungeprüft (src/core/graph/nodes/variable/Variables.ts:32 → writePort in src/core/graph/liveObjects.ts:101). Eine Liste mit Items: Loot kann so zur Laufzeit fremde Items bekommen, etwa aus Join lists oder aus einer gemischten Liste.
  • Der List-Node (ListLiteral, src/core/graph/nodes/data/literals.ts:58) hat keine Einstellung Type. Wer eine typisierte Liste im Graph neu aufbaut, bekommt eine gemischte.

Zu bauen (Vorschlag)

  • Beim Schreiben in eine Listen-Variable mit Item-Typ fallen Items weg, die nicht passen. Die Konsole meldet es mit derselben Regel und demselben Wortlaut wie Add item.
  • List bekommt die Einstellung Type (Mixed oder ein Struct-Asset), wie Add item.
  • Tests: Unit für das Schreiben (passendes Item bleibt, fremdes fällt weg, Meldung in der Konsole), Katalogfälle für List mit Typ, Gegenprobe.

Offen (mit Vorschlag)

  1. Nur die fremden Items weglassen oder den ganzen Wert ablehnen? Vorschlag: nur die fremden weglassen, so wie Add item einen einzelnen Wert weglässt. Die Variable behält den Rest.
  2. Auch Struct-Variablen mit Typ (#253) prüfen, wenn ein Struct mit anderen Feldern hineingeschrieben wird? Heute bringt nur das Laden einen Wert in Form, zur Laufzeit prüft niemand. Vorschlag: ja, mit derselben Regel.
Aus #254 („Not done: writing a variable does not check the type, the List node offers no type.“) und deiner Antwort dort: „typed lists dürfen nur den passenden typed structs erhalten“. ## Befund - Seit #254 prüfen `Add item` und `Set item` mit gesetztem *Type*, ob ein Wert genau die Felder des Struct-Assets hat. Alles andere lassen sie weg und melden es in der Konsole (`src/core/graph/nodes/data/AddItem.ts:20`, `fitsType` in `SetItem.ts`). - Der `Variables`-Node auf *Set* schreibt dagegen jeden Wert ungeprüft (`src/core/graph/nodes/variable/Variables.ts:32` → `writePort` in `src/core/graph/liveObjects.ts:101`). Eine Liste mit *Items: Loot* kann so zur Laufzeit fremde Items bekommen, etwa aus `Join lists` oder aus einer gemischten Liste. - Der `List`-Node (`ListLiteral`, `src/core/graph/nodes/data/literals.ts:58`) hat keine Einstellung *Type*. Wer eine typisierte Liste im Graph neu aufbaut, bekommt eine gemischte. ## Zu bauen (Vorschlag) - Beim Schreiben in eine Listen-Variable mit Item-Typ fallen Items weg, die nicht passen. Die Konsole meldet es mit derselben Regel und demselben Wortlaut wie `Add item`. - `List` bekommt die Einstellung *Type* (Mixed oder ein Struct-Asset), wie `Add item`. - Tests: Unit für das Schreiben (passendes Item bleibt, fremdes fällt weg, Meldung in der Konsole), Katalogfälle für `List` mit Typ, Gegenprobe. ## Offen (mit Vorschlag) 1. **Nur die fremden Items weglassen oder den ganzen Wert ablehnen?** Vorschlag: nur die fremden weglassen, so wie `Add item` einen einzelnen Wert weglässt. Die Variable behält den Rest. 2. **Auch Struct-Variablen mit Typ** (#253) prüfen, wenn ein Struct mit anderen Feldern hineingeschrieben wird? Heute bringt nur das Laden einen Wert in Form, zur Laufzeit prüft niemand. Vorschlag: ja, mit derselben Regel.
meleki added the new label 2026-09-29 18:26:30 +02:00
  1. passt
  2. passt, selbe Regel
1. passt 2. passt, selbe Regel
admin removed the new label 2026-09-29 18:40:07 +02:00
admin added this to the Development project 2026-09-29 18:40:10 +02:00
admin moved this to Next in Development on 2026-09-29 18:40:12 +02:00
Author
Owner

Done in 0f6e628, wiki 5952fa0 (Structs, Architecture, Development).

What changes

  • Typed lists: when a graph writes a list into a list variable with a type, every item that does not have exactly the fields of the type is left out. The rest of the list is written. The console names each item left out on its own line, in the style of Add item: Set loots: 5 is no Loot – left out.
    • The same holds for typed list fields inside a struct variable and for lists inside typed items, at any depth.
  • Typed struct variables: a struct with a field the type does not have is not written, and neither is a value that is no struct at all (… is no Loot – not set). A struct with missing fields merges in as before, so a Pack with only one field keeps working. That is the option chosen for point 2.
  • Where it applies: the Variables node (own variables of the behavior and Variables assets) and the Properties node when it sets a behavior variable of another object.
  • List node: new setting Type. With a type the list behaves like a typed list variable:
    • items are shaped to the type and marked, + Item adds an item of the type, field names are fixed
    • items follow changes to the struct asset
    • a list holding anything other than structs refuses the type, with a console line
    • deleting the type counts the node, and For each over a typed List offers Split into Loot fields
    • the mark never reaches the running game

Different from the proposal
Setting the List node back to None removes the marks, while a list variable keeps them. A node list has no per-item type row, so marked items would be locked there with no way to free them. The values stay, and undo brings everything back.

Under the hood

  • Ports learn their declaration through GraphLookup: what a variable declares about its type, and which behavior owns a graph. The node cache is cleared on every project change, so a port follows a type change.
  • The rule lives in the new src/core/graph/typedValues.ts. fitsType moved there from SetItem, so all checks sit in one place.
  • tests/core/kinds.test.ts assumed the value is the first parameter of a literal. Type now comes first on the List node, so the test finds the value by its key. The intent is unchanged.

Tests

gate (melektaus-atx)    198 files, 2869 tests, CHECK EXIT 0 (2856 + 13)
e2e 55                  ALL PASSED - 19 checks (+55j write at runtime, +2 for 55k List node with a real mouse)
e2e 54                  ALL PASSED - 16 checks
smokes                  24 / 19 / 21, SMOKES EXIT 0
  • Counter-checks work, each bent on its own in a container copy:

    Bent Failing tests
    items not filtered 4
    struct always accepted 1
    no owner for the graph 3 (the Variables asset path stays green, as expected)
    mark kept at runtime 2
    no alignment on the List node 4
  • Screenshot of 55k checked: Type shows "Loot 55", both items have fixed fields, the node reads "Type: Loot 55", and the refusal is in the console.

  • The e2e total of 1606 is computed (1603 + 3). CI is still switched off, so there is no run for 0f6e628. The last run, for cbda6d6, confirmed 1603.

Done in `0f6e628`, wiki `5952fa0` (*Structs*, *Architecture*, *Development*). **What changes** - **Typed lists:** when a graph writes a list into a list variable with a type, every item that does not have exactly the fields of the type is left out. The rest of the list is written. The console names each item left out on its own line, in the style of *Add item*: `Set loots: 5 is no Loot – left out`. - The same holds for typed list fields inside a struct variable and for lists inside typed items, at any depth. - **Typed struct variables:** a struct with a field the type does not have is not written, and neither is a value that is no struct at all (`… is no Loot – not set`). A struct with missing fields merges in as before, so a `Pack` with only one field keeps working. That is the option chosen for point 2. - **Where it applies:** the `Variables` node (own variables of the behavior and Variables assets) and the `Properties` node when it sets a behavior variable of another object. - **`List` node:** new setting *Type*. With a type the list behaves like a typed list variable: - items are shaped to the type and marked, *+ Item* adds an item of the type, field names are fixed - items follow changes to the struct asset - a list holding anything other than structs refuses the type, with a console line - deleting the type counts the node, and *For each* over a typed `List` offers *Split into Loot fields* - the mark never reaches the running game **Different from the proposal** Setting the `List` node back to *None* **removes** the marks, while a list variable keeps them. A node list has no per-item type row, so marked items would be locked there with no way to free them. The values stay, and undo brings everything back. **Under the hood** - Ports learn their declaration through `GraphLookup`: what a variable declares about its type, and which behavior owns a graph. The node cache is cleared on every project change, so a port follows a type change. - The rule lives in the new `src/core/graph/typedValues.ts`. `fitsType` moved there from `SetItem`, so all checks sit in one place. - `tests/core/kinds.test.ts` assumed the value is the first parameter of a literal. *Type* now comes first on the `List` node, so the test finds the value by its key. The intent is unchanged. **Tests** ``` gate (melektaus-atx) 198 files, 2869 tests, CHECK EXIT 0 (2856 + 13) e2e 55 ALL PASSED - 19 checks (+55j write at runtime, +2 for 55k List node with a real mouse) e2e 54 ALL PASSED - 16 checks smokes 24 / 19 / 21, SMOKES EXIT 0 ``` - Counter-checks work, each bent on its own in a container copy: | Bent | Failing tests | |---|---| | items not filtered | 4 | | struct always accepted | 1 | | no owner for the graph | 3 (the Variables asset path stays green, as expected) | | mark kept at runtime | 2 | | no alignment on the `List` node | 4 | - Screenshot of 55k checked: *Type* shows "Loot 55", both items have fixed fields, the node reads "Type: Loot 55", and the refusal is in the console. - The e2e total of 1606 is computed (1603 + 3). CI is still switched off, so there is no run for `0f6e628`. The last run, for `cbda6d6`, confirmed 1603.
admin moved this to Done in Development on 2026-09-30 22:10:37 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#271