Add the Variable node and show the variable name in node titles
Get/Set variable nodes now title themselves "Get <name>" / "Set <name>", and
the new Variable node just "<name>"; the title is the same folded or open,
and a collapsed node shrinks to it. The redundant "Variable: <name>" row is
gone unless the variable was deleted ("<name>?" is the only hint then).
The Variable node sets its value when an exec flow arrives and exposes the
value at any time. Its output is read when a downstream node pulls it, not
frozen at the write, so count = count + 1 is one Variable node plus an Add.
Get variable keeps reading once per pulse: switching it would change the
behaviour of existing games.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5f8a308d62
commit
e9fa592078
19 files changed
+354
-38
No files matched your search
@@ -35,7 +35,22 @@ const logicGraph = {
|
||||
};
|
||||
|
||||
export async function variableNodes(t) {
|
||||
const { check, sleep, evaluate, json, shot, click, locate, undo, entity, asset, mutate, stop } = t;
|
||||
const {
|
||||
check,
|
||||
sleep,
|
||||
evaluate,
|
||||
json,
|
||||
shot,
|
||||
click,
|
||||
locate,
|
||||
undo,
|
||||
entity,
|
||||
asset,
|
||||
mutate,
|
||||
stop,
|
||||
typeText,
|
||||
press,
|
||||
} = t;
|
||||
const portAt = (nodeId, key, isOutput) =>
|
||||
json(`__gm.graph.portAt(${JSON.stringify(nodeId)}, ${JSON.stringify(key)}, ${isOutput})`);
|
||||
const portsOf = async (nodeId) =>
|
||||
@@ -216,6 +231,76 @@ export async function variableNodes(t) {
|
||||
JSON.stringify(helper),
|
||||
);
|
||||
|
||||
// 23i. The Variable node: picked from the palette, titled by the variable picked in the inspector,
|
||||
// and in the run `vz = vz + 1` once a frame – its own output feeding its input via Add.
|
||||
const nodeIds = async () => (await asset('vp-logic')).graph.nodes.map((n) => n.id);
|
||||
const idsBefore = await nodeIds();
|
||||
const centre = await json('__gm.graph.center()');
|
||||
// Below the Owner node; centre + (250, 250) would land on the Pack.
|
||||
await click(centre.x - 250, centre.y + 250, 'right');
|
||||
await sleep(150);
|
||||
// Its description is the one that says "any time"; "variable" would put Get variable first.
|
||||
await typeText('any time');
|
||||
await sleep(200);
|
||||
await press('Enter');
|
||||
await sleep(300);
|
||||
const added = (await asset('vp-logic')).graph.nodes.find((n) => !idsBefore.includes(n.id));
|
||||
check('the palette offers the Variable node', added?.type === 'Variable', JSON.stringify(added));
|
||||
const variableId = added?.id ?? '';
|
||||
const titleOf = (id) => json(`__gm.graph.nodeLabel(${JSON.stringify(id)})`);
|
||||
const untitled = await titleOf(variableId);
|
||||
// The node's own title says "Variable" too, and the canvas is drawn first.
|
||||
const picker = await json(`__gm.inspectorField('Variable', true)`);
|
||||
await click(picker.x, picker.y);
|
||||
await sleep(200);
|
||||
await clickLast('vz');
|
||||
await sleep(300);
|
||||
check(
|
||||
'picking its variable makes that the title, and drops the row that would repeat it',
|
||||
untitled === 'Variable' &&
|
||||
(await titleOf(variableId)) === 'vz' &&
|
||||
(await json(`__gm.graph.nodeSettings(${JSON.stringify(variableId)})`)).length === 0,
|
||||
JSON.stringify({ untitled, titled: await titleOf(variableId), picker }),
|
||||
);
|
||||
await shot('05-variable-node');
|
||||
|
||||
await mutate(`
|
||||
const g = __gm.state.project.assets.find((x) => x.id === 'vp-logic').graph;
|
||||
g.nodes.push(
|
||||
${JSON.stringify(node('vp-add', 'Add', 800, 200, { b: 1 }))},
|
||||
${JSON.stringify(node('vp-set-vx', 'SetVariable', 800, 400, { variable: 'vx' }))},
|
||||
${JSON.stringify(node('vp-set-gone', 'SetVariable', 800, 500, { variable: 'gone' }))},
|
||||
);
|
||||
g.edges.push(
|
||||
${JSON.stringify(edge('vp-e7', 'vp-move', 'exec', variableId, 'exec'))},
|
||||
${JSON.stringify(edge('vp-e8', variableId, 'value', 'vp-add', 'a'))},
|
||||
${JSON.stringify(edge('vp-e9', 'vp-add', 'result', variableId, 'value'))},
|
||||
);
|
||||
`);
|
||||
await sleep(300);
|
||||
const settingsOf = (id) => json(`__gm.graph.nodeSettings(${JSON.stringify(id)})`);
|
||||
const named = { title: await titleOf('vp-set-vx'), rows: await settingsOf('vp-set-vx') };
|
||||
const gone = { title: await titleOf('vp-set-gone'), rows: await settingsOf('vp-set-gone') };
|
||||
check(
|
||||
'Set variable names its variable too, and a deleted one keeps the row that marks it',
|
||||
named.title === 'Set vx' &&
|
||||
named.rows.length === 0 &&
|
||||
gone.title === 'Set gone' &&
|
||||
JSON.stringify(gone.rows) === '["Variable: gone?"]',
|
||||
JSON.stringify({ named, gone }),
|
||||
);
|
||||
|
||||
await t.play();
|
||||
await sleep(1000);
|
||||
const counted = (await entity('vp-brain'))?.props.vz;
|
||||
await stop();
|
||||
await sleep(300);
|
||||
check(
|
||||
'in the run it reads through its own output and writes the sum back, so vz climbs',
|
||||
typeof counted === 'number' && counted > 20,
|
||||
`vz = ${counted} after ~1 s`,
|
||||
);
|
||||
|
||||
await mutate(`
|
||||
const p = __gm.state.project;
|
||||
p.assets = p.assets.filter((a) => a.id !== 'vp-logic');
|
||||
|
||||
Reference in new issue
Block a user