Let a variable hold a list

A variable could only be a number, a text or a yes/no, so every set of values had
to be smuggled through a string - which is where Tetris got its unreadable
"03066326048763714" colours from. A list is now a value of its own, with an item
kind (number, text, yes/no, colour) that decides how the inspector reads the one
comma-separated line it is typed as, and eight nodes to work with: List, Fill,
Count, Item at, Set item, Sub list, Join lists, Index of.

Two traps came with it. An array is typeof 'object', so every place that told a
value from an entity had to learn the difference, or a list would have been
passed around as a game object. And a value was compared by identity in three
places - with lists that marks everything as an overridden property after each
reload, so those comparisons now compare contents.

There is no list of objects: a list is written to the project file and an object
is a live handle that no reload survives. A set of objects stays a list of names.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-09 21:26:31 +02:00
1 parent c6f907b4e0
commit a9c3111377
25 files changed
+469 -25

No files matched your search

+10 -2
View File
@@ -14,7 +14,7 @@ import {
} from '../../core/graph';
import type { BehaviorAsset } from '../../core/model/Asset';
import type { Project } from '../../core/model/Project';
import type { PropertyValue } from '../../core/model/Properties';
import { isList, type PropertyValue } from '../../core/model/Properties';
import { assetRefLabel } from '../../core/properties/assetRef';
import type { PropertyDef } from '../../core/properties/PropertySchema';
import { formatNumber, Theme, textStyle, type TextStyleToken, truncate, Widget } from '../../ui';
@@ -58,6 +58,8 @@ export function portColor(type: PortType): number {
return c.portString;
case 'object':
return c.portObject;
case 'list':
return c.portList;
case 'any':
return c.portAny;
}
@@ -295,7 +297,7 @@ function formatParam(
asset &&
!asset.variables.some((v) => v.key === value)
)
return `${value}?`;
return `${asString(value)}?`;
return formatValue(value);
}
@@ -303,5 +305,11 @@ function formatValue(value: Value): string {
// Whole numbers stay bare to keep nodes narrow; fractions match the field that edits them.
if (typeof value === 'number') return Number.isInteger(value) ? String(value) : formatNumber(value);
if (typeof value === 'boolean') return value ? 'true' : 'false';
// A list can hold hundreds of items – shown whole it would stretch the node across the graph.
if (isList(value)) {
if (value.length === 0) return 'empty';
const head = value.slice(0, 4).map(formatValue).join(', ');
return value.length > 4 ? `${head}, … (${value.length})` : head;
}
return asString(value);
}