@aura3d/scripting 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +32 -2
- package/src/AdaptiveDifficultyFixtures.ts +0 -324
- package/src/AnalyticsPrivacyFixtures.ts +0 -182
- package/src/AnimationNodeCategories.ts +0 -10
- package/src/AnimationVisualNodes.ts +0 -44
- package/src/Behavior.ts +0 -11
- package/src/BehaviorHost.ts +0 -51
- package/src/BehaviorRegistry.ts +0 -22
- package/src/BehaviorSystem.ts +0 -103
- package/src/BehaviorTree.ts +0 -234
- package/src/CloudServiceFixtures.ts +0 -225
- package/src/CulturalBehaviorFixtures.ts +0 -262
- package/src/DecisionTree.ts +0 -162
- package/src/GOAP.ts +0 -150
- package/src/HTN.ts +0 -178
- package/src/LearningAgentFixtures.ts +0 -184
- package/src/NetworkReplicationFixtures.ts +0 -440
- package/src/Perception.ts +0 -163
- package/src/PlayerBehaviorTelemetryFixtures.ts +0 -257
- package/src/ProceduralContentAdaptationFixtures.ts +0 -205
- package/src/ScriptContext.ts +0 -34
- package/src/StateMachine.ts +0 -138
- package/src/UtilityAI.ts +0 -158
- package/src/VisualGraph.ts +0 -236
- package/src/VisualGraphContext.ts +0 -138
- package/src/VisualGraphExecutor.ts +0 -709
- package/src/VisualNode.ts +0 -44
- package/src/VisualNodeCatalog.ts +0 -202
- package/src/WeaponSystem.ts +0 -793
- package/src/index.ts +0 -178
- package/tests/scripting.test.ts +0 -253
- package/tsconfig.json +0 -7
package/src/index.ts
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
export type { Behavior, BehaviorPhase } from "./Behavior";
|
|
2
|
-
export {
|
|
3
|
-
BehaviorAction,
|
|
4
|
-
BehaviorCondition,
|
|
5
|
-
BehaviorSelector,
|
|
6
|
-
BehaviorSequence,
|
|
7
|
-
BehaviorTree,
|
|
8
|
-
BehaviorTreeNode,
|
|
9
|
-
Blackboard
|
|
10
|
-
} from "./BehaviorTree";
|
|
11
|
-
export type {
|
|
12
|
-
BehaviorTreeContext,
|
|
13
|
-
BehaviorTreeStatus,
|
|
14
|
-
BehaviorTreeTickResult,
|
|
15
|
-
BlackboardChange,
|
|
16
|
-
BlackboardValue
|
|
17
|
-
} from "./BehaviorTree";
|
|
18
|
-
export { PerceptionSensor } from "./Perception";
|
|
19
|
-
export type {
|
|
20
|
-
PerceptionHit,
|
|
21
|
-
PerceptionMemory,
|
|
22
|
-
PerceptionPoint,
|
|
23
|
-
PerceptionSensorOptions,
|
|
24
|
-
PerceptionSnapshot,
|
|
25
|
-
PerceptionTarget
|
|
26
|
-
} from "./Perception";
|
|
27
|
-
export { UtilityAI, UtilityAction, UtilityConsideration } from "./UtilityAI";
|
|
28
|
-
export type {
|
|
29
|
-
UtilityActionOptions,
|
|
30
|
-
UtilityActionScore,
|
|
31
|
-
UtilityConsiderationOptions,
|
|
32
|
-
UtilityContext,
|
|
33
|
-
UtilityCurve,
|
|
34
|
-
UtilityScoring
|
|
35
|
-
} from "./UtilityAI";
|
|
36
|
-
export { State, StateMachine } from "./StateMachine";
|
|
37
|
-
export type { StateMachineSnapshot, StateTransition, StateTransitionCondition } from "./StateMachine";
|
|
38
|
-
export { GOAPAction, GOAPPlanner, WorldState } from "./GOAP";
|
|
39
|
-
export type { GOAPActionOptions, GOAPPlan, GOAPPlannerOptions, GOAPStateShape, GOAPValue } from "./GOAP";
|
|
40
|
-
export { HTNPlanner, HTNTask } from "./HTN";
|
|
41
|
-
export type { HTNCompoundTaskOptions, HTNPlan, HTNPlannerOptions, HTNPrimitiveTaskOptions, HTNTaskMethod, HTNTaskResult, HTNTaskType } from "./HTN";
|
|
42
|
-
export { DecisionTree } from "./DecisionTree";
|
|
43
|
-
export type { DecisionAction, DecisionCondition, DecisionTreeContext, DecisionTreeDecision, DecisionTreeNode, DecisionTreeNodeType, DecisionTreeStats } from "./DecisionTree";
|
|
44
|
-
export { sampleAdaptiveDifficultyFixture } from "./AdaptiveDifficultyFixtures";
|
|
45
|
-
export type {
|
|
46
|
-
AdaptiveDifficultyAdjustment,
|
|
47
|
-
AdaptiveDifficultyChangeType,
|
|
48
|
-
AdaptiveDifficultyFixture,
|
|
49
|
-
AdaptiveDifficultyFixtureOptions,
|
|
50
|
-
AdaptiveDifficultyMetricSummary,
|
|
51
|
-
AdaptiveDifficultyMetricType,
|
|
52
|
-
AdaptiveDifficultyStrategy,
|
|
53
|
-
AdaptiveDifficultyTriggeredRule
|
|
54
|
-
} from "./AdaptiveDifficultyFixtures";
|
|
55
|
-
export { sampleAnalyticsPrivacyFixture } from "./AnalyticsPrivacyFixtures";
|
|
56
|
-
export type {
|
|
57
|
-
AnalyticsConsentCategory,
|
|
58
|
-
AnalyticsPrivacyFixture,
|
|
59
|
-
AnalyticsPrivacyFixtureOptions,
|
|
60
|
-
AnalyticsProviderMode
|
|
61
|
-
} from "./AnalyticsPrivacyFixtures";
|
|
62
|
-
export { sampleCulturalBehaviorFixture } from "./CulturalBehaviorFixtures";
|
|
63
|
-
export type {
|
|
64
|
-
CulturalBehaviorFixture,
|
|
65
|
-
CulturalBehaviorFixtureOptions,
|
|
66
|
-
CulturalCommunicationStyle,
|
|
67
|
-
CulturalEntityFixture,
|
|
68
|
-
CulturalPersonalSpace,
|
|
69
|
-
CulturalRelationship,
|
|
70
|
-
CultureDescriptor,
|
|
71
|
-
ProxemicZone
|
|
72
|
-
} from "./CulturalBehaviorFixtures";
|
|
73
|
-
export { sampleCloudServiceFixture } from "./CloudServiceFixtures";
|
|
74
|
-
export type { CloudFixtureServiceStatus, CloudServiceFixture, CloudServiceFixtureOptions } from "./CloudServiceFixtures";
|
|
75
|
-
export { sampleLearningAgentFixture } from "./LearningAgentFixtures";
|
|
76
|
-
export type { LearningAgentFixture, LearningAgentFixtureOptions } from "./LearningAgentFixtures";
|
|
77
|
-
export { sampleNetworkReplicationFixture } from "./NetworkReplicationFixtures";
|
|
78
|
-
export type {
|
|
79
|
-
NetworkDeltaSummary,
|
|
80
|
-
NetworkEntityState,
|
|
81
|
-
NetworkInputFrame,
|
|
82
|
-
NetworkInterestSummary,
|
|
83
|
-
NetworkInterpolationSummary,
|
|
84
|
-
NetworkPredictionSummary,
|
|
85
|
-
NetworkReplicationFixture,
|
|
86
|
-
NetworkReplicationFixtureOptions,
|
|
87
|
-
NetworkReplicationMode
|
|
88
|
-
} from "./NetworkReplicationFixtures";
|
|
89
|
-
export { samplePlayerBehaviorTelemetryFixture } from "./PlayerBehaviorTelemetryFixtures";
|
|
90
|
-
export type {
|
|
91
|
-
PlayerBehaviorPatternTelemetry,
|
|
92
|
-
PlayerBehaviorTelemetryFixture,
|
|
93
|
-
PlayerBehaviorTelemetryOptions,
|
|
94
|
-
PlayerEngagementLevel,
|
|
95
|
-
PlayerEventCategory,
|
|
96
|
-
PlayerEventSeverity,
|
|
97
|
-
PlayerPlaystyle,
|
|
98
|
-
PlayerSkillAssessmentTelemetry,
|
|
99
|
-
PlayerSkillLevel
|
|
100
|
-
} from "./PlayerBehaviorTelemetryFixtures";
|
|
101
|
-
export { sampleProceduralContentAdaptationFixture } from "./ProceduralContentAdaptationFixtures";
|
|
102
|
-
export type {
|
|
103
|
-
AdaptiveAiStrategy,
|
|
104
|
-
GeneratedContentDifficulty,
|
|
105
|
-
GeneratedContentTelemetry,
|
|
106
|
-
GeneratedContentType,
|
|
107
|
-
ProceduralContentAdaptationFixture,
|
|
108
|
-
ProceduralContentAdaptationOptions
|
|
109
|
-
} from "./ProceduralContentAdaptationFixtures";
|
|
110
|
-
export { sampleFpsEnemyTactics, sampleFpsHudOverlay, sampleFpsLevelLayout, sampleFpsWeaponCycle, samplePowerUpEffect, sampleSpaceShooterWave, sampleWeaponBurst } from "./WeaponSystem";
|
|
111
|
-
export type {
|
|
112
|
-
FpsEnemyTacticalState,
|
|
113
|
-
FpsEnemyTacticsInput,
|
|
114
|
-
FpsEnemyTacticsSample,
|
|
115
|
-
FpsFiringMode,
|
|
116
|
-
FpsHudOverlayInput,
|
|
117
|
-
FpsHudOverlaySample,
|
|
118
|
-
FpsLevelCorridor,
|
|
119
|
-
FpsLevelLayoutInput,
|
|
120
|
-
FpsLevelLayoutSample,
|
|
121
|
-
FpsLevelPickup,
|
|
122
|
-
FpsLevelPoint,
|
|
123
|
-
FpsLevelRoom,
|
|
124
|
-
FpsPickupType,
|
|
125
|
-
FpsWeaponCycleInput,
|
|
126
|
-
FpsWeaponCycleSample,
|
|
127
|
-
FpsWeaponType,
|
|
128
|
-
PowerUpEffectInput,
|
|
129
|
-
PowerUpEffectSample,
|
|
130
|
-
SpaceShooterEnemyType,
|
|
131
|
-
SpaceShooterFormation,
|
|
132
|
-
SpaceShooterPowerUpType,
|
|
133
|
-
SpaceShooterSpawn,
|
|
134
|
-
SpaceShooterWaveInput,
|
|
135
|
-
SpaceShooterWaveSample,
|
|
136
|
-
WeaponBurst,
|
|
137
|
-
WeaponBurstInput,
|
|
138
|
-
WeaponKind,
|
|
139
|
-
WeaponProjectile
|
|
140
|
-
} from "./WeaponSystem";
|
|
141
|
-
export { BehaviorHost } from "./BehaviorHost";
|
|
142
|
-
export type { BehaviorHostOptions } from "./BehaviorHost";
|
|
143
|
-
export { BehaviorRegistry } from "./BehaviorRegistry";
|
|
144
|
-
export type { BehaviorFactory } from "./BehaviorRegistry";
|
|
145
|
-
export { BehaviorSystem } from "./BehaviorSystem";
|
|
146
|
-
export type { BehaviorError, BehaviorSystemUpdateOptions } from "./BehaviorSystem";
|
|
147
|
-
export { ScriptContext } from "./ScriptContext";
|
|
148
|
-
export type { ScriptContextOptions } from "./ScriptContext";
|
|
149
|
-
export { deserializeGraph, serializeGraph, validateGraph } from "./VisualGraph";
|
|
150
|
-
export type { SerializedVisualGraph, VisualEdge, VisualGraph } from "./VisualGraph";
|
|
151
|
-
export { VisualGraphExecutor } from "./VisualGraphExecutor";
|
|
152
|
-
export type { VisualExecutionResult } from "./VisualGraphExecutor";
|
|
153
|
-
export type {
|
|
154
|
-
VisualAnimationControllerState,
|
|
155
|
-
VisualAnimationEvent,
|
|
156
|
-
VisualCameraState,
|
|
157
|
-
VisualCollisionEvent,
|
|
158
|
-
VisualCombatEvent,
|
|
159
|
-
VisualGraphDiagnostic,
|
|
160
|
-
VisualGraphExecutionContext,
|
|
161
|
-
VisualGraphSideEffect,
|
|
162
|
-
VisualGraphValidationOptions,
|
|
163
|
-
VisualInputSet,
|
|
164
|
-
VisualInputSnapshot,
|
|
165
|
-
VisualOverlapResult,
|
|
166
|
-
VisualPhysicsBodyState,
|
|
167
|
-
VisualRaycastHit,
|
|
168
|
-
VisualRuntimeNodeState,
|
|
169
|
-
VisualStateCollection,
|
|
170
|
-
VisualVector3
|
|
171
|
-
} from "./VisualGraphContext";
|
|
172
|
-
export { createVisualNode, getVisualNodeDefinition, listVisualNodeDefinitions } from "./VisualNodeCatalog";
|
|
173
|
-
export type { VisualNodeCategory, VisualNodeDefinition } from "./VisualNodeCatalog";
|
|
174
|
-
export { animationNodeCategories } from "./AnimationNodeCategories";
|
|
175
|
-
export type { AnimationNodeCategory } from "./AnimationNodeCategories";
|
|
176
|
-
export { animationVisualNodeDefinitions } from "./AnimationVisualNodes";
|
|
177
|
-
export { validateNode } from "./VisualNode";
|
|
178
|
-
export type { VisualNode, VisualPort, VisualPortDirection, VisualPortType } from "./VisualNode";
|
package/tests/scripting.test.ts
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import {
|
|
4
|
-
BehaviorHost,
|
|
5
|
-
BehaviorSystem,
|
|
6
|
-
createVisualNode,
|
|
7
|
-
listVisualNodeDefinitions,
|
|
8
|
-
validateGraph,
|
|
9
|
-
VisualGraphExecutor,
|
|
10
|
-
type VisualGraphExecutionContext
|
|
11
|
-
} from "../src/index";
|
|
12
|
-
|
|
13
|
-
test("BehaviorSystem runs start before update and fixed phase separately", async () => {
|
|
14
|
-
const calls: string[] = [];
|
|
15
|
-
const host = new BehaviorHost();
|
|
16
|
-
host.attach({
|
|
17
|
-
onStart: () => calls.push("start"),
|
|
18
|
-
onFixedUpdate: () => calls.push("fixed"),
|
|
19
|
-
onUpdate: () => calls.push("update")
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const system = new BehaviorSystem();
|
|
23
|
-
system.registerHost(host);
|
|
24
|
-
await system.fixedUpdate({ fixedDeltaSeconds: 1 / 60 });
|
|
25
|
-
await system.update({ deltaSeconds: 1 / 30 });
|
|
26
|
-
await system.update({ deltaSeconds: 1 / 30 });
|
|
27
|
-
|
|
28
|
-
assert.deepEqual(calls, ["fixed", "start", "update", "update"]);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("Visual graph validates ports and executes simple constants plus add", () => {
|
|
32
|
-
const graph = {
|
|
33
|
-
nodes: [
|
|
34
|
-
{ id: "a", kind: "const", data: { value: 2 }, ports: [{ id: "out", direction: "output", type: "number" }] },
|
|
35
|
-
{ id: "b", kind: "const", data: { value: 3 }, ports: [{ id: "out", direction: "output", type: "number" }] },
|
|
36
|
-
{ id: "sum", kind: "add", ports: [{ id: "in", direction: "input", type: "number" }] }
|
|
37
|
-
],
|
|
38
|
-
edges: [
|
|
39
|
-
{ fromNode: "a", fromPort: "out", toNode: "sum", toPort: "in" },
|
|
40
|
-
{ fromNode: "b", fromPort: "out", toNode: "sum", toPort: "in" }
|
|
41
|
-
]
|
|
42
|
-
} as const;
|
|
43
|
-
|
|
44
|
-
assert.deepEqual(validateGraph(graph), []);
|
|
45
|
-
assert.equal(new VisualGraphExecutor().execute(graph).values.get("sum"), 5);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("Visual graph executes catalog math and logic nodes", () => {
|
|
49
|
-
const graph = {
|
|
50
|
-
nodes: [
|
|
51
|
-
createVisualNode("const", "a", { value: 12 }),
|
|
52
|
-
createVisualNode("const", "b", { value: 5 }),
|
|
53
|
-
createVisualNode("subtract", "delta"),
|
|
54
|
-
createVisualNode("lessEqual", "bounded", { b: 7 })
|
|
55
|
-
],
|
|
56
|
-
edges: [
|
|
57
|
-
{ fromNode: "a", fromPort: "out", toNode: "delta", toPort: "a" },
|
|
58
|
-
{ fromNode: "b", fromPort: "out", toNode: "delta", toPort: "b" },
|
|
59
|
-
{ fromNode: "delta", fromPort: "out", toNode: "bounded", toPort: "a" }
|
|
60
|
-
]
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const result = new VisualGraphExecutor().execute(graph);
|
|
64
|
-
|
|
65
|
-
assert.equal(result.values.get("delta"), 7);
|
|
66
|
-
assert.equal(result.values.get("bounded"), true);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("Visual graph executes bounded flow-control catalog nodes", () => {
|
|
70
|
-
const graph = {
|
|
71
|
-
nodes: [
|
|
72
|
-
createVisualNode("branch", "branch", { condition: false }),
|
|
73
|
-
createVisualNode("forRange", "loop", { startIndex: 1, endIndex: 4 }),
|
|
74
|
-
createVisualNode("gate", "gate", { startClosed: true })
|
|
75
|
-
],
|
|
76
|
-
edges: []
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const result = new VisualGraphExecutor().execute(graph);
|
|
80
|
-
|
|
81
|
-
assert.equal(result.values.get("branch.selected"), "false");
|
|
82
|
-
assert.equal(result.values.get("branch.false"), true);
|
|
83
|
-
assert.deepEqual(result.values.get("loop.indices"), [1, 2, 3]);
|
|
84
|
-
assert.equal(result.values.get("gate.isOpen"), false);
|
|
85
|
-
assert.equal(result.values.get("gate.out"), false);
|
|
86
|
-
assert.ok(result.blockedClaims.includes("Unreal Blueprint parity"));
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("Visual node catalog exposes Aura3D 1.0.5 runtime-facing node families", () => {
|
|
90
|
-
const definitions = listVisualNodeDefinitions();
|
|
91
|
-
const byCategory = new Map(definitions.map((definition) => [definition.kind, definition.category]));
|
|
92
|
-
|
|
93
|
-
for (const [kind, category] of Object.entries({
|
|
94
|
-
onFrame: "runtime",
|
|
95
|
-
translate: "runtime",
|
|
96
|
-
pressed: "input",
|
|
97
|
-
combo: "input",
|
|
98
|
-
restartClip: "animation",
|
|
99
|
-
onAnimationEvent: "animation",
|
|
100
|
-
setVelocity: "physics",
|
|
101
|
-
onCollisionEnter: "physics",
|
|
102
|
-
openHitbox: "combat",
|
|
103
|
-
onHit: "combat",
|
|
104
|
-
follow: "camera",
|
|
105
|
-
captureSnapshot: "evidence",
|
|
106
|
-
assertState: "evidence"
|
|
107
|
-
})) {
|
|
108
|
-
assert.equal(byCategory.get(kind), category);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
test("Animation visual scripting nodes are cataloged and execute deterministic commands", () => {
|
|
113
|
-
const definitions = listVisualNodeDefinitions();
|
|
114
|
-
const byKind = new Map(definitions.map((definition) => [definition.kind, definition]));
|
|
115
|
-
|
|
116
|
-
for (const kind of ["setScene", "sayLine", "frameCharacter", "playMusic", "waitForBeat", "captureThumbnail"]) {
|
|
117
|
-
assert.ok(byKind.has(kind), `missing animation visual node ${kind}`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const graph = {
|
|
121
|
-
nodes: [
|
|
122
|
-
createVisualNode("setScene", "scene", { sceneId: "garden" }),
|
|
123
|
-
createVisualNode("sayLine", "line", { speakerId: "hero", text: "Hello moon.", emotion: "happy" }),
|
|
124
|
-
createVisualNode("captureThumbnail", "thumb", { time: 1, path: "thumb.png" })
|
|
125
|
-
],
|
|
126
|
-
edges: []
|
|
127
|
-
};
|
|
128
|
-
const result = new VisualGraphExecutor().execute(graph);
|
|
129
|
-
|
|
130
|
-
assert.equal((result.values.get("scene.command") as { kind?: string }).kind, "animation.scene.setScene");
|
|
131
|
-
assert.equal((result.values.get("line.command") as { kind?: string }).kind, "animation.dialogue.sayLine");
|
|
132
|
-
assert.equal((result.values.get("thumb.command") as { kind?: string }).kind, "animation.publishing.captureThumbnail");
|
|
133
|
-
assert.equal(result.sideEffects.length, 3);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test("Visual graph validation catches missing inputs and invalid deterministic context references", () => {
|
|
137
|
-
const context: VisualGraphExecutionContext = {
|
|
138
|
-
runtimeNodes: [{ id: "player" }],
|
|
139
|
-
animationControllers: [{ id: "playerAnim", clips: ["Idle", "LightPunch"], morphTargets: ["AA", "FV"] }],
|
|
140
|
-
physicsBodies: [{ id: "playerBody" }]
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const missingInputGraph = {
|
|
144
|
-
nodes: [createVisualNode("getNode", "missing-node-id")],
|
|
145
|
-
edges: []
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
assert.ok(validateGraph(missingInputGraph).some((error) => error.includes("Missing required input")));
|
|
149
|
-
|
|
150
|
-
const invalidGraph = {
|
|
151
|
-
nodes: [
|
|
152
|
-
createVisualNode("getNode", "bad-runtime-node", { nodeId: "ghost" }),
|
|
153
|
-
createVisualNode("playClip", "bad-clip", { controllerId: "playerAnim", clip: "Uppercut" }),
|
|
154
|
-
createVisualNode("setMorphTarget", "bad-morph", { controllerId: "playerAnim", morphTarget: "ZZ", weight: 1 }),
|
|
155
|
-
createVisualNode("setVelocity", "bad-body", { bodyId: "ghostBody", velocity: { x: 1, y: 0, z: 0 } })
|
|
156
|
-
],
|
|
157
|
-
edges: []
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const errors = validateGraph(invalidGraph, { context, strictReferences: true });
|
|
161
|
-
|
|
162
|
-
assert.ok(errors.some((error) => error.includes("Unknown runtime node id")));
|
|
163
|
-
assert.ok(errors.some((error) => error.includes("Unknown animation clip")));
|
|
164
|
-
assert.ok(errors.some((error) => error.includes("Unknown morph target")));
|
|
165
|
-
assert.ok(errors.some((error) => error.includes("Unknown physics body id")));
|
|
166
|
-
|
|
167
|
-
const cycleGraph = {
|
|
168
|
-
nodes: [createVisualNode("add", "a"), createVisualNode("add", "b")],
|
|
169
|
-
edges: [
|
|
170
|
-
{ fromNode: "a", fromPort: "out", toNode: "b", toPort: "in" },
|
|
171
|
-
{ fromNode: "b", fromPort: "out", toNode: "a", toPort: "in" }
|
|
172
|
-
]
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
assert.ok(validateGraph(cycleGraph).some((error) => error.includes("Visual graph cycle detected")));
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
test("Visual graph executes deterministic runtime input animation physics combat camera and evidence hooks", () => {
|
|
179
|
-
const context: VisualGraphExecutionContext = {
|
|
180
|
-
frame: 12,
|
|
181
|
-
time: 0.2,
|
|
182
|
-
dt: 1 / 60,
|
|
183
|
-
runtimeNodes: [{ id: "player", position: { x: 1, y: 0, z: 0 }, visible: true }],
|
|
184
|
-
input: {
|
|
185
|
-
pressed: ["attack"],
|
|
186
|
-
held: { right: true },
|
|
187
|
-
buffered: ["dash"],
|
|
188
|
-
combos: ["light-light"],
|
|
189
|
-
axes: { moveX: 1 }
|
|
190
|
-
},
|
|
191
|
-
animationControllers: [
|
|
192
|
-
{
|
|
193
|
-
id: "playerAnim",
|
|
194
|
-
currentClip: "Idle",
|
|
195
|
-
clipTime: 0.24,
|
|
196
|
-
clips: ["Idle", "LightPunch"],
|
|
197
|
-
morphTargets: ["AA"],
|
|
198
|
-
events: [{ type: "hitbox.open", controllerId: "playerAnim", clip: "LightPunch", time: 0.12, payload: { hitboxId: "player.light" } }]
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
physicsBodies: [{ id: "playerBody", velocity: { x: 0, y: 0, z: 0 }, grounded: true }],
|
|
202
|
-
collisionEvents: [{ type: "enter", bodyId: "playerBody", otherBodyId: "dummyBody" }],
|
|
203
|
-
combatEvents: [{ type: "hit", actorId: "player", targetId: "dummy", hitboxId: "player.light", amount: 8 }],
|
|
204
|
-
camera: { id: "mainCamera", position: { x: 0, y: 2, z: 5 } },
|
|
205
|
-
evidence: { proofId: "visual-scripting-runtime" }
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
const graph = {
|
|
209
|
-
nodes: [
|
|
210
|
-
createVisualNode("onFrame", "frame"),
|
|
211
|
-
createVisualNode("pressed", "attack-pressed", { action: "attack" }),
|
|
212
|
-
createVisualNode("axis", "move-axis", { axis: "moveX" }),
|
|
213
|
-
createVisualNode("translate", "move", { nodeId: "player", delta: { x: 0.25, y: 0, z: 0 } }),
|
|
214
|
-
createVisualNode("restartClip", "attack-clip", { controllerId: "playerAnim", clip: "LightPunch" }),
|
|
215
|
-
createVisualNode("onAnimationEvent", "hitbox-event", { controllerId: "playerAnim", eventType: "hitbox.open", clip: "LightPunch" }),
|
|
216
|
-
createVisualNode("openHitbox", "open-hitbox", { hitboxId: "player.light", ownerId: "player", damage: 8 }),
|
|
217
|
-
createVisualNode("setMorphTarget", "mouth-aa", { controllerId: "playerAnim", morphTarget: "AA", weight: 0.7 }),
|
|
218
|
-
createVisualNode("setVelocity", "velocity", { bodyId: "playerBody", velocity: { x: 3, y: 0, z: 0 } }),
|
|
219
|
-
createVisualNode("onCollisionEnter", "collision", { bodyId: "playerBody", otherBodyId: "dummyBody" }),
|
|
220
|
-
createVisualNode("onHit", "hit", { actorId: "player", hitboxId: "player.light" }),
|
|
221
|
-
createVisualNode("follow", "camera-follow", { targetId: "player", stiffness: 0.85 }),
|
|
222
|
-
createVisualNode("captureSnapshot", "snapshot", { label: "visual-scripting-runtime" }),
|
|
223
|
-
createVisualNode("assertState", "assert-attack", { actual: true, expected: true })
|
|
224
|
-
],
|
|
225
|
-
edges: []
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
assert.deepEqual(validateGraph(graph, { context }), []);
|
|
229
|
-
|
|
230
|
-
const result = new VisualGraphExecutor(context).execute(graph);
|
|
231
|
-
const second = new VisualGraphExecutor(context).execute(graph);
|
|
232
|
-
|
|
233
|
-
assert.equal(result.values.get("attack-pressed"), true);
|
|
234
|
-
assert.equal(result.values.get("move-axis"), 1);
|
|
235
|
-
assert.equal(result.values.get("hitbox-event.fired"), true);
|
|
236
|
-
assert.equal(result.values.get("collision.collided"), true);
|
|
237
|
-
assert.equal(result.values.get("hit.hit"), true);
|
|
238
|
-
assert.equal(result.values.get("assert-attack.passed"), true);
|
|
239
|
-
|
|
240
|
-
assert.deepEqual((result.values.get("move.command") as { position: unknown }).position, { x: 1.25, y: 0, z: 0 });
|
|
241
|
-
assert.deepEqual(result.sideEffects.map((effect) => effect.kind), [
|
|
242
|
-
"runtime.translate",
|
|
243
|
-
"animation.restartClip",
|
|
244
|
-
"combat.openHitbox",
|
|
245
|
-
"animation.setMorphTarget",
|
|
246
|
-
"physics.setVelocity",
|
|
247
|
-
"camera.follow",
|
|
248
|
-
"evidence.captureSnapshot",
|
|
249
|
-
"evidence.assertState"
|
|
250
|
-
]);
|
|
251
|
-
assert.deepEqual(result.sideEffects, second.sideEffects);
|
|
252
|
-
assert.deepEqual(result.diagnostics, []);
|
|
253
|
-
});
|