Behaviors with Blueprint-style node graph, graph editor tab and BehaviorSystem

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-07 12:44:43 +02:00
1 parent d4b1ffa051
commit 922774778b
36 files changed
+2969 -147

No files matched your search

+18 -1
View File
@@ -1,3 +1,5 @@
import type { Graph } from '../graph/Graph';
import type { PropertyDef } from '../properties/PropertySchema';
import type { AssetType } from './AssetTypes';
import type { PropertyBag } from './Properties';
import type { SceneObject } from './SceneObject';
@@ -24,8 +26,23 @@ export interface SceneAsset extends AssetBase {
objects: SceneObject[];
}
export type Asset = SpriteAsset | CameraAsset | SceneAsset;
/**
* A behavior is logic: a node graph plus the variables it declares. Variables are ordinary
* properties – `variables` is the asset's own property schema, `props` holds their default
* values, and placed instances override them like any other property.
*/
export interface BehaviorAsset extends AssetBase {
type: 'behavior';
variables: PropertyDef[];
graph: Graph;
}
export type Asset = SpriteAsset | CameraAsset | SceneAsset | BehaviorAsset;
export function isSceneAsset(asset: Asset): asset is SceneAsset {
return asset.type === 'scene';
}
export function isBehaviorAsset(asset: Asset): asset is BehaviorAsset {
return asset.type === 'behavior';
}
+10 -2
View File
@@ -1,5 +1,5 @@
/** All asset types known in phase 1. Scenes are assets too, but cannot be placed in scenes. */
export const ASSET_TYPES = ['scene', 'camera', 'sprite'] as const;
/** All asset types. Scenes are assets too, but cannot be placed in scenes. */
export const ASSET_TYPES = ['scene', 'camera', 'sprite', 'behavior'] as const;
export type AssetType = (typeof ASSET_TYPES)[number];
@@ -13,3 +13,11 @@ export function isPlaceableType(type: AssetType): type is PlaceableAssetType {
export function isAssetType(value: unknown): value is AssetType {
return typeof value === 'string' && (ASSET_TYPES as readonly string[]).includes(value);
}
/**
* Types drawn as editor symbols (icon in the overlay layer) instead of as scene content.
* They exist in the scene for their position, not for their looks.
*/
export function isSymbolType(type: AssetType): boolean {
return type === 'camera' || type === 'behavior';
}
+13 -1
View File
@@ -13,9 +13,21 @@ export interface SceneObject {
/** World position plus draw order (`z`). */
position: Position;
overrides: PropertyBag;
/**
* Another object of the same scene this one acts on (used by behaviors: "the owner").
* Empty string = none. Any object may carry one, only behaviors interpret it.
*/
ownerId: string;
}
/** Creates a scene object; `z` defaults to 0 when the caller only has a 2D point. */
export function createSceneObject(id: string, assetId: string, position: Vec2 | Position): SceneObject {
return { id, assetId, name: '', position: { x: position.x, y: position.y, z: 'z' in position ? position.z : 0 }, overrides: {} };
return {
id,
assetId,
name: '',
position: { x: position.x, y: position.y, z: 'z' in position ? position.z : 0 },
overrides: {},
ownerId: '',
};
}