Let each variable of a behavior choose whether calls keep it (#229)
game-maker / gate (push) Successful in 3m13s
game-maker / suite (push) Failing after 8m46s

The first version of #229 put a Keep state switch on the Run behavior
node. The user wanted it where the variable is declared instead. Whether
a value lives on belongs to the variable, not to every call site.

- The node switch keepState is gone again. RunBehavior, CallResult and
  nested.ts are back to what they were before #229.
- BehaviorAsset.keptVariables lists the kept names. It lives on the
  asset and not in PropertyDef, because that is the schema of every
  inspector row.
- A variable added from now on starts with Keep on. Variables in
  existing projects start with Keep off, so old projects run unchanged.
- SetVariableKeptCommand flips the switch as one undo step. Add, remove
  and rename carry the list along. Loading drops names that are not
  declared.
- The interpreter keeps only the listed variables, per Run behavior
  node and per object as before. The others start at their defaults.
- Local state machines in a called behavior start empty on every call
  again, as before #229. Global and scene machines are unchanged.
- The inspector shows a Keep button in each variable row of a behavior.
  Its state is part of the asset signature, so a click redraws the row.
  Without that the button kept its old look until the inspector was
  reopened.

Found: the project Garden of Sacrifices still has keepState = true on
the call Player -> Character Movement. It is ignored now. Direction
there predates the switch, so Keep is off until set by hand.

Tests:
- ./check.sh: 163 files, 2392 tests, CHECK EXIT 0 (before 2388)
- tests/core/keep-state.test.ts rewritten, 15 tests
- e2e 19: ALL PASSED, 35 checks. 19c-ii now clicks the Keep button
  of a new variable: on when added, off by a click, on again, off
  after undo.
- Counter-checks, each fails its own test: keep list ignored (2),
  states kept (1), new variable not kept (8), rename drops the list
  (1), no Keep button (e2e 19c-ii).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-09-25 15:50:59 +02:00
1 parent 7c70245c79
commit 454d202109
14 files changed
+333 -149

No files matched your search

+21 -1
View File
@@ -52,8 +52,15 @@ export interface VariableEditing {
addField: (kind: StructFieldKind) => void;
}
/** A behavior's switch for one variable: carried on from one `Run behavior` call to the next (#229). */
export interface VariableKeep {
on: boolean;
set: (on: boolean) => void;
}
export interface VariableOptions {
edit?: VariableEditing;
keep?: VariableKeep;
/** ↺/↑ on the first row: an override covers a whole struct, so its fields share them. */
actions?: RowActions;
}
@@ -69,7 +76,7 @@ export function buildVariable(
handlers: FieldHandlers,
options: VariableOptions = {},
): FieldRow {
const { edit, actions } = options;
const { edit, keep, actions } = options;
const name = nameCell(def.key, 0, edit && ((next) => edit.rename(next)));
const head = gridRow(0, markLabel(def.kind), name);
let setValue: (next: PropertyValue) => void = () => {};
@@ -79,6 +86,7 @@ export function buildVariable(
} else {
setValue = addValue(head, createField(host, def, value, handlers));
}
if (keep) head.add(keepButton(keep));
if (edit) head.add(removeButton(edit.remove));
const refreshActions = actions ? attachRowActions(head, actions) : () => {};
host.body.add(head);
@@ -95,6 +103,18 @@ export function buildVariable(
};
}
/** Lit while the variable is kept; a click flips it. */
function keepButton(keep: VariableKeep): Button {
const button = new Button('Keep', {
variant: 'ghost',
style: 'small',
toggle: true,
onClick: () => keep.set(!keep.on),
});
button.setToggled(keep.on);
return button;
}
/** One row per field, each with its own value; returns the setter that pushes a bundle into them. */
function structFieldRows(
host: InspectorHost,