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)
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.
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
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 Noneremoves 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.
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 #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
Add itemundSet itemmit 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,fitsTypeinSetItem.ts).Variables-Node auf Set schreibt dagegen jeden Wert ungeprüft (src/core/graph/nodes/variable/Variables.ts:32→writePortinsrc/core/graph/liveObjects.ts:101). Eine Liste mit Items: Loot kann so zur Laufzeit fremde Items bekommen, etwa ausJoin listsoder aus einer gemischten Liste.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)
Add item.Listbekommt die Einstellung Type (Mixed oder ein Struct-Asset), wieAdd item.Listmit Typ, Gegenprobe.Offen (mit Vorschlag)
Add itemeinen einzelnen Wert weglässt. Die Variable behält den Rest.Done in
0f6e628, wiki5952fa0(Structs, Architecture, Development).What changes
Set loots: 5 is no Loot – left out.… is no Loot – not set). A struct with missing fields merges in as before, so aPackwith only one field keeps working. That is the option chosen for point 2.Variablesnode (own variables of the behavior and Variables assets) and thePropertiesnode when it sets a behavior variable of another object.Listnode: new setting Type. With a type the list behaves like a typed list variable:Listoffers Split into Loot fieldsDifferent from the proposal
Setting the
Listnode 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
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.src/core/graph/typedValues.ts.fitsTypemoved there fromSetItem, so all checks sit in one place.tests/core/kinds.test.tsassumed the value is the first parameter of a literal. Type now comes first on theListnode, so the test finds the value by its key. The intent is unchanged.Tests
Counter-checks work, each bent on its own in a container copy:
ListnodeScreenshot 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, forcbda6d6, confirmed 1603.