A behavior that has a Start and an End node can now be dropped into any other graph as a node of its own. What is declared on the start node becomes the inputs of that node, what hangs on the end node its outputs; the port list is derived from the sub graph, not copied, so declaring a port in one graph grows the node in the other without touching it. The node carries the behavior's name and the palette lists behaviors by name, so a call is one grab instead of a node plus a dropdown. An embedded behavior has no object and therefore no place for variables: every call starts on the asset defaults and communicates only through its ports. That is the conservative direction - state can still be added later, and shared state already has a home in a behavior object in the scene. Node ids are unique per graph only, so each call gets its own pulse cache; without that, two graphs would collide. Renaming a port used to silently drop the value typed on the calling node. It is carried along now, project wide, like the edges.
51 lines
1.6 KiB
JavaScript
51 lines
1.6 KiB
JavaScript
/**
|
||
* Small factories for writing project documents by hand (the seed scripts). They produce the
|
||
* exact shape `src/core/store/serialize.ts` reads; optional fields get their defaults.
|
||
*/
|
||
|
||
/** A scene object (also a container template entry). Position defaults to the origin. */
|
||
export const sceneObject = (
|
||
id,
|
||
assetId,
|
||
{ name = '', x = 0, y = 0, z = 0, overrides = {}, parentId = '', instanceEdits, editorOffset } = {},
|
||
) => ({
|
||
id,
|
||
assetId,
|
||
name,
|
||
position: { x, y, z },
|
||
overrides,
|
||
parentId,
|
||
...(instanceEdits ? { instanceEdits } : {}),
|
||
...(editorOffset ? { editorOffset } : {}),
|
||
});
|
||
|
||
/**
|
||
* The id an object of a placed container resolves to: `<instance>~<template ids>`. A placed
|
||
* container stores nothing but itself, so this is how its content is addressed – in the editor,
|
||
* in a running game and in the check scripts alike (see `src/core/model/instance.ts`).
|
||
*/
|
||
export const instanceChild = (instanceId, ...templatePath) => `${instanceId}~${templatePath.join('/')}`;
|
||
|
||
/** A graph edge from `from.fromPort` to `to.toPort`. */
|
||
export const edge = (id, from, fromPort, to, toPort) => ({
|
||
id,
|
||
from: { node: from, port: fromPort },
|
||
to: { node: to, port: toPort },
|
||
});
|
||
|
||
/** A graph node; `params` holds settings and inline input values alike. `ports` only on start/end. */
|
||
export const node = (id, type, x, y, params = {}, ports) => ({
|
||
id,
|
||
type,
|
||
x,
|
||
y,
|
||
params,
|
||
...(ports ? { ports } : {}),
|
||
});
|
||
|
||
/** A port a behavior's start or end node declares. */
|
||
export const port = (key, kind) => ({ key, kind });
|
||
|
||
/** A behavior variable declaration. */
|
||
export const variable = (key, kind, value) => ({ key, label: key, kind, default: value });
|