Shader assets: graph-built shaders, the Shader tab and sprite rows from the graph (#62)
game-maker / suite (push) Failing after 3m59s

A shader is an asset carrying a node graph (Texture color, Output, Property,
Color, Add/Subtract/Multiply/Divide, Mix, Luminance) that compiles to the GLSL
fragment of a Pixi filter. The Shader tab reuses the Behavior canvas; a sprite
wears a shader through its Shader picker, and the rows below it are the
graph's Property nodes. Property schema, resolution and deviation take the
project because a sprite's rows now live in another asset. The built-in
registry of the prototype is gone; "Adjust colors" ships as a graph in the
fixture and the three example games.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-12 22:41:14 +02:00
1 parent 6141d07d4f
commit 42cafa7543
62 files changed
+1682 -144

No files matched your search

+8 -4
View File
@@ -52,7 +52,7 @@ describe('editing one field of a struct', () => {
const object = (): SceneObject =>
findScene(f.state.project, f.sceneId)!.objects.find((o) => o.id === f.objectId)!;
const structDef = () => {
const def = requirePropDef(asset(), 'piece');
const def = requirePropDef(f.state.project, asset(), 'piece');
if (def.kind !== 'struct') throw new Error('piece is not a struct');
return def;
};
@@ -62,7 +62,7 @@ describe('editing one field of a struct', () => {
structFieldsOf<SceneObject>({ state: f.state }, structDef(), {
target: object,
read: (o) => o.overrides.piece,
current: (o) => resolveSceneObjectProps(asset(), o).piece,
current: (o) => resolveSceneObjectProps(f.state.project, asset(), o).piece,
write: (o, value) => (o.overrides.piece = value),
remove: (o) => delete o.overrides.piece,
commit: (value) => new SetOverrideCommand(f.sceneId, f.objectId, 'piece', value),
@@ -99,7 +99,11 @@ describe('editing one field of a struct', () => {
objectHandlers()({ key: 'x', kind: 'number' }).onChange(9);
f.state.execute(new SetAssetPropertyCommand(f.behaviorId, 'piece', { x: 3, y: 99, tag: 'T' }));
// The whole bundle is overridden now, so the asset moving on no longer reaches y.
expect(resolveSceneObjectProps(asset(), object()).piece).toEqual({ x: 9, y: 4, tag: 'T' });
expect(resolveSceneObjectProps(f.state.project, asset(), object()).piece).toEqual({
x: 9,
y: 4,
tag: 'T',
});
});
it('takes the stored value where that already is the resolved one – the dense asset bag', () => {
@@ -114,6 +118,6 @@ describe('editing one field of a struct', () => {
},
);
handlers({ key: 'y', kind: 'number' }).onChange(8);
expect(resolveAssetProps(asset()).piece).toEqual({ x: 3, y: 8, tag: 'T' });
expect(resolveAssetProps(f.state.project, asset()).piece).toEqual({ x: 3, y: 8, tag: 'T' });
});
});