Let Spawn take an asset over an edge and find a child by name (#237)
An asset could only be picked as a setting on the Spawn node. It could not be wired in, held in a variable or put into a list. Finding an object below the own one needed a scene-wide search by name. - "Asset" is now a kind like Animation or Sound: port, variable, list item and a new "Asset" literal node, with its own cube icon. - Spawn and Is asset have an `asset` input. It uses the key of the old setting, so a saved asset reads as the value of the input and older projects keep spawning without a migration. - New node "Child by name" searches below an object level by level. A child wins over a grandchild of the same name. Nothing found or no object gives null. Tests: - ./check.sh: 168 files, 2453 tests, CHECK EXIT 0. - 9 new unit tests in tests/core/asset-kind.test.ts, catalog cases for Spawn, Is asset, Child by name and the literal. - e2e 6z-ii (2 checks): node rows and a real drag of the literal onto `asset`. e2e 6: 119 checks passed. Spawn checks in 3 and 9 passed. - Counter-checks: depth-first search fails 1, Spawn reading only the old setting fails 3, runtime ignoring the parent fails 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1b3cb625a3
commit
923baf2557
18 files changed
+345
-24
No files matched your search
@@ -423,6 +423,23 @@ const CASES: Record<string, Case[]> = {
|
||||
},
|
||||
{ name: 'an unknown name is null', inputs: { name: 'Ghost' }, outputs: { object: null } },
|
||||
],
|
||||
ChildByName: [
|
||||
{
|
||||
name: 'asks the context below the object it is given',
|
||||
inputs: { object: fakeEntity('Player'), name: 'Hitbox' },
|
||||
context: {
|
||||
childByName: (parent, name) =>
|
||||
parent.name === 'Player' && name === 'Hitbox' ? fakeEntity('Hitbox') : null,
|
||||
},
|
||||
outputs: { child: fakeEntity('Hitbox') },
|
||||
},
|
||||
{
|
||||
name: 'an unknown name is null',
|
||||
inputs: { object: fakeEntity('Player'), name: 'Ghost' },
|
||||
outputs: { child: null },
|
||||
},
|
||||
{ name: 'no object is null', inputs: { object: null, name: 'Hitbox' }, outputs: { child: null } },
|
||||
],
|
||||
NameOf: [
|
||||
{ name: 'reads the name', inputs: { object: fakeEntity('Coin') }, outputs: { name: 'Coin' } },
|
||||
{ name: 'no object is the empty name', inputs: { object: null }, outputs: { name: '' } },
|
||||
@@ -430,10 +447,14 @@ const CASES: Record<string, Case[]> = {
|
||||
IsAsset: [
|
||||
{
|
||||
name: 'matches the asset id',
|
||||
inputs: { object: fakeEntity('Coin', 0, 'coin') },
|
||||
params: { asset: 'coin' },
|
||||
inputs: { object: fakeEntity('Coin', 0, 'coin'), asset: 'coin' },
|
||||
outputs: { result: true },
|
||||
},
|
||||
{
|
||||
name: 'another asset does not match',
|
||||
inputs: { object: fakeEntity('Coin', 0, 'coin'), asset: 'gem' },
|
||||
outputs: { result: false },
|
||||
},
|
||||
{
|
||||
name: 'no asset chosen never matches',
|
||||
inputs: { object: fakeEntity('Coin', 0, 'coin') },
|
||||
@@ -504,6 +525,10 @@ const CASES: Record<string, Case[]> = {
|
||||
{ name: 'outputs the id it was set to', params: { value: 'anim-1' }, outputs: { value: 'anim-1' } },
|
||||
{ name: 'unset is no animation', outputs: { value: '' } },
|
||||
],
|
||||
Asset: [
|
||||
{ name: 'outputs the id it was set to', params: { value: 'crate' }, outputs: { value: 'crate' } },
|
||||
{ name: 'unset is no asset', outputs: { value: '' } },
|
||||
],
|
||||
Add: [
|
||||
{ name: 'adds', inputs: { a: 2, b: 3 }, outputs: { result: 5 } },
|
||||
{ name: 'numeric text is coerced', inputs: { a: '2', b: 3 }, outputs: { result: 5 } },
|
||||
@@ -1322,6 +1347,22 @@ const CASES: Record<string, Case[]> = {
|
||||
],
|
||||
Tile: [{ name: 'hands out the tile chosen', params: { value: 'door' }, outputs: { value: 'door' } }],
|
||||
Spawn: [
|
||||
{
|
||||
name: 'places the asset that arrives on its input, local to the parent',
|
||||
inputs: { asset: 'crate', x: 1, y: 2, z: 3, parent: fakeEntity('Box') },
|
||||
context: {
|
||||
spawn: (assetId, position, parent) =>
|
||||
assetId === 'crate' &&
|
||||
position.x === 1 &&
|
||||
position.y === 2 &&
|
||||
position.z === 3 &&
|
||||
parent?.name === 'Box'
|
||||
? fakeEntity('Crate')
|
||||
: null,
|
||||
},
|
||||
next: 'exec',
|
||||
outputs: { object: fakeEntity('Crate') },
|
||||
},
|
||||
{
|
||||
name: 'no asset chosen logs a hint and continues with no object',
|
||||
next: 'exec',
|
||||
|
||||
Reference in new issue
Block a user