Add a node that names the render layer of an object (#305)
game-maker / gate (push) Successful in 3m14s
game-maker / suite (push) Failing after 14m18s

The issue asked for Set render layer, Set sees and Render layer of. As
with #211, a probe showed that writing already works. A Properties
node of the object's type writes Render layer during a run, Inherit
included, and one of type Camera writes Sees. The next picture follows
both. As agreed, only Render layer of is built, and writing stays with
Properties.

- Render layer of is a data node with the input object and the outputs
  name and number. It answers the layer that holds, so an object
  without a choice of its own names its parent's.
- NodeContext.renderLayerOf answers the number with the same rule the
  drawing uses (renderLayerAlong). The new field renderLayers on
  GraphLookup brings the names to the node.
- hasRenderLayer in PropertySchema says which types are drawn.
- Decided here: for an object that is not drawn (a camera, a
  behavior, a collider) the name is empty and the number -1, as Layer
  of does without a collider.

Changing the render layer or Sees during a run had no test so far.
Three unit tests now hold the proof from the issue.

Tests:
- Gate: 231 files, 3534 tests (3526 + 8), exit 0
- e2e 6: 149 checks passed, e2e 63: 13 checks passed (+1)
- Unit: the coin moves into the overlay with Set and back with
  Inherit, a HUD container takes its sprite along, the main camera sees
  a second layer once its Sees is set, and Render layer of names the
  inherited layer, and none for a behavior
- Node catalog: four cases for Render layer of
- 63c3 moves a sprite onto UI in a Play run: the main camera no longer
  draws it, and the log reads "UI" and "1"
- Three counter-probes fail 1, 1 and 2 tests: without inheriting in
  the node, without the check for a drawn type, and without
  inheriting in the drawing
- "layer of" in the palette still finds Layer of first (6z-x)
- The e2e sum is 1731 (1730 plus 1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-03 19:25:47 +02:00
1 parent 70f3608733
commit d9c6bbfa4d
12 files changed
+250 -8

No files matched your search

+50 -1
View File
@@ -4,7 +4,8 @@
* a green sprite of the overlay with z -10 covers a red one of the main camera with z 1000, and
* what a camera does not see stays away – a yellow `UI` sprite in front of the main camera, a blue
* `Default` one in front of the overlay. Switched to no overlay, the second camera draws nothing.
* `Is hovered` and `Mouse position` find the mouse through the overlay camera too (#304).
* `Is hovered` and `Mouse position` find the mouse through the overlay camera too (#304), and a
* graph moves a sprite onto another layer while the game runs (#305).
* Then the main camera wears a shader over its picture (#299), in the Game tab and, switched on in
* the eye, in the scene view.
*
@@ -187,6 +188,54 @@ export async function renderLayers(t) {
JSON.stringify({ hovered, overlayX }),
);
// 63c3. (#305) A graph moves the red square A onto `UI` with a Properties node once the game runs:
// the main camera no longer draws it, and `Render layer of` names its new layer.
const switchGraph = {
nodes: [
node('rl63-start', 'OnStart', 0),
node('rl63-a-find', 'ObjectByName', 0, { name: 'A 63' }),
{
...node('rl63-set', 'Properties', 200, { objectType: 'sprite', renderLayer: 1 }),
ports: [{ key: 'renderLayer', kind: 'number', write: true }],
},
node('rl63-of', 'RenderLayerOf', 200),
node('rl63-name', 'Log', 400),
node('rl63-number', 'Log', 600),
],
edges: [
edge('rl63-s1', 'rl63-start', 'exec', 'rl63-set', 'exec'),
edge('rl63-s2', 'rl63-set', 'exec', 'rl63-name', 'exec'),
edge('rl63-s3', 'rl63-name', 'exec', 'rl63-number', 'exec'),
edge('rl63-s4', 'rl63-a-find', 'object', 'rl63-set', 'object'),
edge('rl63-s5', 'rl63-a-find', 'object', 'rl63-of', 'object'),
edge('rl63-s6', 'rl63-of', 'name', 'rl63-name', 'message'),
edge('rl63-s7', 'rl63-of', 'number', 'rl63-number', 'message'),
],
};
await mutate(`
const p = __gm.state.project;
const scene = __gm.state.activeScene;
p.assets.push({ id: 'rl63-switch', type: 'behavior', name: 'Switch 63', props: { enabled: true, runInEditor: false }, variables: [], graph: ${JSON.stringify(switchGraph)} });
${MAKE_OBJECT}
scene.objects.push(make('rl63-switcher', 'rl63-switch', '', 0, 'Switch 63'));
`);
await play();
await sleep(400);
const switched = await picture();
const named = (await json('__gm.world()'))?.log.slice(-2) ?? [];
await stop();
await mutate(`
const p = __gm.state.project;
const scene = __gm.state.activeScene;
scene.objects = scene.objects.filter((o) => o.id !== 'rl63-switcher');
p.assets = p.assets.filter((a) => a.id !== 'rl63-switch');
`);
check(
'a graph moves a sprite onto UI while the game runs, and Render layer of names it',
!switched.main.includes('rl63-a') && !is(switched.right, RED) && JSON.stringify(named) === '["UI","1"]',
JSON.stringify({ switched, named }),
);
// 63d. The project settings list the render layers, apart from the collision layers.
await t.clickToolbar('menu');
await clickText('Project settings…');