Three stores, three importers and three pickers that differ only in their type are one of each (#85)
game-maker / gate (push) Successful in 1m33s
game-maker / suite (push) Successful in 5m46s

Refactoring round one: HttpFontStore/HttpSoundStore/HttpTextureStore collapse into a generic
HttpFileStore over a FileStore contract; fontImport/soundImport/textureImport share assetImport
with an ImportKind per sort; ImagePicker/FontPicker/SoundPicker sit on FilePicker and describe
only their row. The group/comment drag logic leaves GraphCanvas for annotationDrag.ts (with its
own unit test), declaredRows.ts replaces the duplicated row build in particles.ts and shaders.ts,
and dead code in font/sound/compile/emission/transform/actions is gone. README: asset list,
check count 958, the two-job CI, the Scenes wiki page.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5.1 committed 2026-09-16 17:38:54 +02:00
1 parent 15bdfdf07a
commit cc6db5f350
42 files changed
+1375 -1650

No files matched your search

+14 -43
View File
@@ -1,7 +1,15 @@
import type { Graph, GraphNode } from '../graph/Graph';
import { type PropertyBag, textOf } from '../model/Properties';
import { declaredNumberRows, PROPERTY_NAME_PARAM } from './declaredRows';
import { type FlatDef, isSpriteProp, isValidFieldName } from './PropertySchema';
export {
PROPERTY_DEFAULT_PARAM,
PROPERTY_MAX_PARAM,
PROPERTY_MIN_PARAM,
PROPERTY_NAME_PARAM,
} from './declaredRows';
/** The sprite property naming the shader asset it wears; `''` is no shader and no render pass. */
export const SHADER_KEY = 'shader';
@@ -10,10 +18,6 @@ export const SHADER_KEY = 'shader';
* GLSL uniform, `default`/`min`/`max` are the row the inspector shows.
*/
export const SHADER_PROPERTY = 'ShaderProperty';
export const PROPERTY_NAME_PARAM = 'name';
export const PROPERTY_DEFAULT_PARAM = 'default';
export const PROPERTY_MIN_PARAM = 'min';
export const PROPERTY_MAX_PARAM = 'max';
export function shaderOf(bag: PropertyBag): string {
return textOf(bag[SHADER_KEY]);
@@ -36,46 +40,13 @@ export function isValidPropertyName(name: string): boolean {
return isValidFieldName(name) && !isSpriteProp(name);
}
/**
* The properties a shader graph declares, in node order: one number row per `Property` node with
* a valid name. A second node with the same name declares nothing new – both read one uniform.
*/
/** The properties a shader graph declares: one row on the sprite and one uniform each. */
export function shaderParamDefs(graph: Graph): FlatDef<'number'>[] {
const rows: FlatDef<'number'>[] = [];
const seen = new Set<string>();
for (const node of graph.nodes) {
if (!isPropertyNode(node)) continue;
const name = propertyName(node);
if (!isValidPropertyName(name) || seen.has(name)) continue;
seen.add(name);
rows.push(propertyRow(name, node.params));
}
return rows;
}
function propertyRow(name: string, params: PropertyBag): FlatDef<'number'> {
const min = numberParam(params, PROPERTY_MIN_PARAM, 0);
const max = numberParam(params, PROPERTY_MAX_PARAM, 1);
const row: FlatDef<'number'> = {
key: name,
label: name,
kind: 'number',
default: numberParam(params, PROPERTY_DEFAULT_PARAM, 0),
min,
step: niceStep(max > min ? max - min : 1),
};
// A max at or below the min would pin the value; treated as "no max" instead.
return max > min ? { ...row, max } : row;
}
function numberParam(params: PropertyBag, key: string, fallback: number): number {
const n = Number(params[key]);
return Number.isFinite(n) ? n : fallback;
}
/** A twentieth of the range's power of ten: 0.05 for 0-4, 0.05 for 0-1, 5 for 0-100. */
function niceStep(range: number): number {
return 10 ** Math.floor(Math.log10(range)) / 20;
return declaredNumberRows(graph, {
isDeclaration: isPropertyNode,
nameOf: propertyName,
isValidName: isValidPropertyName,
});
}
/** What a property placed from the palette is called: `value`, then `value2`, `value3` … */