@moku-labs/game 0.0.3 → 0.2.0

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.
@@ -1,6 +1,6 @@
1
- import { A as TrackSegment, At as Json, I as ComponentType, M as AnyComponent, P as AnyComponentValue, R as Entity, St as Api, T as MotionHandle, _t as TypeTag, h as Api$2, k as TrackOptions, nn as Require, q as Api$1, t as Api$3, x as Ease } from "./types-Cjf3ywai.mjs";
2
- import { o as Events$1, t as Api$4 } from "./types-DgwbzDLP.mjs";
3
- import { F as Events$2, H as InputApi, I as I18nApi, L as Message, c as UiNode, i as Finding, n as ElementChange, o as JsxState, r as ElementMotion, v as StylesState } from "./types-C0SLQsx0.mjs";
1
+ import { A as TrackSegment, At as Json, E as NumericFields, F as ComponentHandle, I as ComponentType, M as AnyComponent, P as AnyComponentValue, R as Entity, St as Api, T as MotionHandle, _t as TypeTag, h as Api$2, k as TrackOptions, nn as Require, q as Api$1, t as Api$3, x as Ease } from "./types-BZ1OLf24.mjs";
2
+ import { o as Events$1, t as Api$4 } from "./types-C47fKNcn.mjs";
3
+ import { F as Events$2, H as InputApi, I as I18nApi, L as Message, c as UiNode, i as Finding, n as ElementChange, o as JsxState, r as ElementMotion, v as StylesState } from "./types-X9jXjka3.mjs";
4
4
  import { Log } from "@moku-labs/common/browser";
5
5
  import { PluginCtx } from "@moku-labs/core";
6
6
  import { Node, Yoga } from "yoga-layout/load";
@@ -739,6 +739,286 @@ type StepMotion = MotionHandle & {
739
739
  advance(deltaMs: number): number;
740
740
  };
741
741
  //#endregion
742
+ //#region src/plugins/anim/timeline/steps.d.ts
743
+ /**
744
+ * Every haptic tick `haptic(kind)` takes, in one frozen list: the three impacts, the selection
745
+ * tick and the three notifications. `platform` checks a kind against it before it plays one.
746
+ *
747
+ * @example
748
+ * ```ts
749
+ * HAPTIC_KINDS.includes("light"); // true
750
+ * ```
751
+ */
752
+ declare const HAPTIC_KINDS: readonly ["light", "medium", "heavy", "selection", "success", "warning", "error"];
753
+ /**
754
+ * Runs the steps one after another. The remainder past a step's end reaches the next step in the
755
+ * same frame, so the tree takes exactly the sum of its durations.
756
+ *
757
+ * @param steps - The steps, in order.
758
+ * @returns The sequence step.
759
+ * @example
760
+ * ```ts
761
+ * sequence(wait(100), mark("done"));
762
+ * // { kind: "sequence", steps: [{ kind: "wait", ms: 100 }, { kind: "mark", name: "done" }] }
763
+ * ```
764
+ */
765
+ declare function sequence(...steps: readonly Step[]): Step;
766
+ /**
767
+ * Runs every step at once and ends with the longest one.
768
+ *
769
+ * @param steps - The steps.
770
+ * @returns The parallel step.
771
+ * @example
772
+ * ```ts
773
+ * parallel(wait(100), wait(300)); // ends after 300 ms
774
+ * ```
775
+ */
776
+ declare function parallel(...steps: readonly Step[]): Step;
777
+ /**
778
+ * Builds one step per item and starts each one `staggerMs` later than the one before. The build
779
+ * function runs here, so no function survives in the data.
780
+ *
781
+ * @param items - What to build a step for.
782
+ * @param staggerMs - Delay between two neighbouring items, in game milliseconds.
783
+ * @param build - Builds the step of one item.
784
+ * @returns The parallel of delayed sequences.
785
+ * @example
786
+ * ```ts
787
+ * stagger(["a", "b"], 60, item => mark(item));
788
+ * // parallel(sequence(wait(0), mark("a")), sequence(wait(60), mark("b")))
789
+ * ```
790
+ */
791
+ declare function stagger<Item>(items: readonly Item[], staggerMs: number, build: (item: Item, index: number) => Step): Step;
792
+ /**
793
+ * Holds still for a while.
794
+ *
795
+ * @param durationMs - How long to wait, in game milliseconds.
796
+ * @returns The wait step.
797
+ * @example
798
+ * ```ts
799
+ * wait(120); // { kind: "wait", ms: 120 }
800
+ * ```
801
+ */
802
+ declare function wait(durationMs: number): Step;
803
+ /**
804
+ * Names a point in the choreography. Reaching it emits `anim:mark`, calls the `onMark` listeners
805
+ * and appends the name to `marks()`. It is the only way out of a timeline.
806
+ *
807
+ * @param name - Name of the mark.
808
+ * @returns The mark step.
809
+ * @example
810
+ * ```ts
811
+ * mark("landed"); // { kind: "mark", name: "landed" }
812
+ * ```
813
+ */
814
+ declare function mark(name: string): Step;
815
+ /**
816
+ * Moves the numeric fields of one component of one target to an exact target value. The component
817
+ * is any handle `world.ecs` takes, so the kit's `Sprite` and `NineSlice` of `defineGame` pass as
818
+ * they are.
819
+ *
820
+ * By default the fields are local: they are written into the target's own `Transform`. With
821
+ * `space: "root"` the `x`, `y`, `rotation` and `scale` of a `Transform` are a root pose, the space
822
+ * `at()` answers in, and are turned into the space of the target's `Parent` when the track starts.
823
+ * That aims a hosted view, such as a board item inside the board slot, at another element. A
824
+ * field the step does not name stays where it is, so under a turned parent name `x` and `y`
825
+ * together. A target without a parent, and a component other than `Transform`, move as in the
826
+ * local space.
827
+ *
828
+ * @param target - The projection key or the entity to animate.
829
+ * @param component - The component to animate.
830
+ * @param to - The numeric target fields.
831
+ * @param options - Duration, easing, delay, the additive flag and the space of the fields.
832
+ * @param options.ms - Duration in game milliseconds.
833
+ * @param options.ease - Easing curve; `"out"` when omitted.
834
+ * @param options.delayMs - How long the track waits before it reads its start values.
835
+ * @param options.additive - `true` adds an offset instead of owning the fields.
836
+ * @param options.space - `"root"` reads the `Transform` fields as a root pose; `"local"` when
837
+ * omitted.
838
+ * @returns The tween step.
839
+ * @example
840
+ * ```ts
841
+ * // An order is delivered: the board item flies out of the scaled board slot onto the order card.
842
+ * const deliverFly = defineAnimation("orders.deliverFly", {
843
+ * slots: { item: type<Target>(), card: type<Target>() },
844
+ * build: ({ item, card }, { at }) =>
845
+ * tween(item, Transform, { x: at(card).x, y: at(card).y, scale: at(card).scale }, {
846
+ * ms: 400, ease: "inCubic", space: "root"
847
+ * })
848
+ * });
849
+ * app.anim.play(deliverFly, {
850
+ * item: { projection: "board.items", key: "i1" },
851
+ * card: { projection: "hud", key: "card0" }
852
+ * });
853
+ * // 400 ms later the item covers the card at the card's size; its Transform stays slot-local
854
+ * ```
855
+ */
856
+ declare function tween<Value extends object>(target: Target, component: ComponentHandle<Value>, to: Partial<NumericFields<Value>>, options: {
857
+ ms: number;
858
+ ease?: Ease;
859
+ delayMs?: number;
860
+ additive?: boolean;
861
+ space?: "local" | "root";
862
+ }): Step;
863
+ /**
864
+ * Writes a component patch at once. Any field may be written, not only the numeric ones. The
865
+ * component is any handle `world.ecs` takes, the kit's `Sprite` and `NineSlice` included.
866
+ *
867
+ * @param target - The projection key or the entity to write.
868
+ * @param component - The component to write.
869
+ * @param patch - The fields to overwrite.
870
+ * @returns The set step.
871
+ * @example
872
+ * ```ts
873
+ * set({ projection: "hud", key: "coins" }, Sprite, { texture: "hud.coin-gold" });
874
+ * // { kind: "set", patch: { texture: "hud.coin-gold" }, ... }
875
+ * ```
876
+ */
877
+ declare function set<Value extends object>(target: Target, component: ComponentHandle<Value>, patch: Partial<Value>): Step;
878
+ /**
879
+ * Plays a frame sprite: one texture key of the list per frame of `fps`, written into `Sprite`.
880
+ *
881
+ * @param target - The projection key or the entity to animate.
882
+ * @param options - The keys, the frame rate and whether the list repeats.
883
+ * @param options.keys - The texture keys, in play order.
884
+ * @param options.fps - Frames per second of the list.
885
+ * @param options.loop - `true` repeats the list until the step is finished.
886
+ * @returns The frames step.
887
+ * @example
888
+ * ```ts
889
+ * frames({ projection: "board", key: "c3" }, { keys: ["fx.pop-1", "fx.pop-2"], fps: 12 });
890
+ * // { kind: "frames", keys: ["fx.pop-1", "fx.pop-2"], fps: 12, loop: false, ... }
891
+ * ```
892
+ */
893
+ declare function frames(target: Target, options: {
894
+ keys: readonly string[];
895
+ fps: number;
896
+ loop?: boolean;
897
+ }): Step;
898
+ /**
899
+ * Makes a temporary entity when the step is reached: a flying coin, a toast sign, a sparkle. The
900
+ * entity is owned by `anim`, drawn in `layer` at `order`, and despawned when the timeline ends, is
901
+ * finished or is cancelled. Later steps of the same timeline aim at it with `spawned(id)`.
902
+ *
903
+ * @param id - Name of the entity inside this timeline; one timeline spawns each id once.
904
+ * @param components - The component values the entity starts with, as `world.ecs.spawn` takes.
905
+ * @param options - Where the entity is drawn.
906
+ * @param options.layer - The layer; `"ui"` when omitted.
907
+ * @param options.order - The draw order inside the layer; `0` when omitted.
908
+ * @returns The spawn step.
909
+ * @example
910
+ * ```ts
911
+ * spawn("coin1", [Sprite({ texture: "ui.icon-coin" }), Transform({ x: 540, y: 900 })], { order: 50 });
912
+ * // { kind: "spawn", id: "coin1", components: [...], layer: "ui", order: 50 }
913
+ * ```
914
+ */
915
+ declare function spawn(id: string, components: readonly AnyComponentValue[], options?: {
916
+ layer?: string;
917
+ order?: number;
918
+ }): Step;
919
+ /**
920
+ * Aims a later step at the entity a `spawn` step of the same timeline made. Before that step is
921
+ * reached nothing answers the id, so a step aimed at it ends silently.
922
+ *
923
+ * @param id - The id the `spawn` step was given.
924
+ * @returns The target.
925
+ * @example
926
+ * ```ts
927
+ * tween(spawned("coin1"), Transform, { x: 40, y: 120 }, { ms: 600, ease: "inCubic" });
928
+ * // { kind: "tween", target: { spawned: "coin1" }, ... }
929
+ * ```
930
+ */
931
+ declare function spawned(id: string): {
932
+ spawned: string;
933
+ };
934
+ /**
935
+ * A sound. `anim` owns the descriptor because it sits below `audio`; `audio` owns the handler,
936
+ * and a game without `audio` plays nothing and hears no error.
937
+ *
938
+ * @param key - Asset key of the sound.
939
+ * @param options - The bus to play it on.
940
+ * @param options.bus - `"sfx"` when omitted.
941
+ * @returns The descriptor, usable as a timeline step and as `fx(...)` in a node.
942
+ * @example
943
+ * ```ts
944
+ * sfx("board.merge"); // { kind: "sfx", payload: { key: "board.merge", bus: "sfx" }, cosmetic: true }
945
+ * ```
946
+ */
947
+ declare function sfx(key: string, options?: {
948
+ bus?: string;
949
+ }): SfxDescriptor;
950
+ /**
951
+ * A haptic tick. `platform` owns the handler; a device without one stays still.
952
+ *
953
+ * @param kind - Which tick to play, one of `HAPTIC_KINDS`, for example `"light"`.
954
+ * @returns The descriptor, usable as a timeline step and as `fx(...)` in a node.
955
+ * @example
956
+ * ```ts
957
+ * haptic("light"); // { kind: "haptic", payload: { kind: "light" }, cosmetic: true }
958
+ * ```
959
+ */
960
+ declare function haptic(kind: HapticKind): HapticDescriptor;
961
+ /**
962
+ * Reserved for Spine and the other external players. It throws until one arrives, so nobody
963
+ * builds a choreography on a door that is not open yet.
964
+ *
965
+ * @param _player - The player that would run the clip.
966
+ * @param _clip - Name of the clip.
967
+ * @throws {Error} Always.
968
+ * @example
969
+ * ```ts
970
+ * external(spine, "idle"); // throws: External players arrive with Spine.
971
+ * ```
972
+ */
973
+ declare function external(_player: ExternalPlayer, _clip: string): never;
974
+ /**
975
+ * Nests one animation inside another. The nested tree is built here, so its marks are reported
976
+ * under the nested id and no function survives in the data. Pass the outer `tools` when the
977
+ * nested `build` reads `at`.
978
+ *
979
+ * @param animation - The animation to nest.
980
+ * @param slots - One target, or a list of targets, per slot of the nested animation.
981
+ * @param tools - The build tools of the outer animation; without them `at` is the identity pose.
982
+ * @returns The use step.
983
+ * @example
984
+ * ```ts
985
+ * use(popCard, { card: { projection: "hud", key: "order" } });
986
+ * // { kind: "use", id: "hud.popCard", step: { kind: "sequence", ... } }
987
+ * ```
988
+ */
989
+ declare function use<Tags extends SlotTags>(animation: AnimationDefinition<Tags>, slots: SlotValues<Tags>, tools?: BuildTools): Step;
990
+ /**
991
+ * The effect descriptor a node awaits to play a choreography. The payload names the animation,
992
+ * so the handler resolves the definition from the registry the features filled.
993
+ *
994
+ * @param animation - The animation to play.
995
+ * @param slots - One target, or a list of targets, per slot.
996
+ * @returns The descriptor, cosmetic, so a failing build never breaks the node.
997
+ * @example
998
+ * ```ts
999
+ * play(coinsFly, { from: { projection: "hud", key: "purse" } });
1000
+ * // { kind: "play", payload: { animation: "hud.coinsFly", slots: { from: { ... } } }, cosmetic: true }
1001
+ * ```
1002
+ */
1003
+ declare function play<Tags extends SlotTags>(animation: AnimationDefinition<Tags>, slots: SlotValues<Tags>): PlayDescriptor;
1004
+ /**
1005
+ * Declares one animation: an id, the slots it takes and the pure function that builds its step
1006
+ * tree. `build` runs once per play, so the same animation may play twice at once.
1007
+ *
1008
+ * @param id - Animation id, unique across the features of a game.
1009
+ * @param spec - The slots and the build function.
1010
+ * @returns The animation as frozen plain data.
1011
+ * @example
1012
+ * ```ts
1013
+ * const coinsFly = defineAnimation("hud.coinsFly", {
1014
+ * slots: { from: type<Target>() },
1015
+ * build: ({ from }) => tween(from, Transform, { scale: 0.4 }, { ms: 600 })
1016
+ * });
1017
+ * coinsFly.id; // "hud.coinsFly"
1018
+ * ```
1019
+ */
1020
+ declare function defineAnimation<Tags extends SlotTags>(id: string, spec: AnimationSpec<Tags>): AnimationDefinition<Tags>;
1021
+ //#endregion
742
1022
  //#region src/plugins/anim/timeline/types.d.ts
743
1023
  /**
744
1024
  * The value of the component a step names, with its shape erased: the value type of
@@ -771,6 +1051,16 @@ type SfxDescriptor = {
771
1051
  };
772
1052
  readonly cosmetic: true;
773
1053
  };
1054
+ /**
1055
+ * One haptic tick a device can play: the impact, selection and notification families of Tauri.
1056
+ * `HAPTIC_KINDS` lists the same seven at runtime.
1057
+ *
1058
+ * @example
1059
+ * ```ts
1060
+ * const kind: HapticKind = "success";
1061
+ * ```
1062
+ */
1063
+ type HapticKind = (typeof HAPTIC_KINDS)[number];
774
1064
  /**
775
1065
  * A haptic tick, owned by `anim` and handled by `platform`. Like `sfx` it is a descriptor and a
776
1066
  * timeline step at once.
@@ -785,7 +1075,7 @@ type SfxDescriptor = {
785
1075
  type HapticDescriptor = {
786
1076
  readonly kind: "haptic";
787
1077
  readonly payload: {
788
- readonly kind: string;
1078
+ readonly kind: HapticKind;
789
1079
  };
790
1080
  readonly cosmetic: true;
791
1081
  };
@@ -1005,7 +1295,7 @@ type RunningTimeline = {
1005
1295
  ended: boolean;
1006
1296
  };
1007
1297
  declare namespace types_d_exports {
1008
- export { AnimApi, AnimCtx, AnimationDefinition, AnimationSpec, AnyAnimationDefinition, BuildTools, Config, Cursor, Deps, ErasedFields, Events, ExternalPlayer, FrameLoop, FramesValue, FxStep, HapticDescriptor, KernelSlice, MarkListener, MotionKeyframe, PlayDescriptor, PlayHandle, Pose, RunningTimeline, SfxDescriptor, SlotRecord, SlotTags, SlotValue, SlotValues, State, Step, StepMotion, Target, TimelineRuntime, Track };
1298
+ export { AnimApi, AnimCtx, AnimationDefinition, AnimationSpec, AnyAnimationDefinition, BuildTools, Config, Cursor, Deps, ErasedFields, Events, ExternalPlayer, FrameLoop, FramesValue, FxStep, HapticDescriptor, HapticKind, KernelSlice, MarkListener, MotionKeyframe, PlayDescriptor, PlayHandle, Pose, RunningTimeline, SfxDescriptor, SlotRecord, SlotTags, SlotValue, SlotValues, State, Step, StepMotion, Target, TimelineRuntime, Track };
1009
1299
  }
1010
1300
  /**
1011
1301
  * What a step and a slot are pointed at: the projection key of a live view or of an element a
@@ -1441,4 +1731,4 @@ type AnimCtx = KernelSlice & {
1441
1731
  readonly deps: Deps;
1442
1732
  };
1443
1733
  //#endregion
1444
- export { Point as C, TextStyles as D, TextStyleInput as E, TextValue as O, Config$2 as S, TextApi as T, Step as _, Config as a, UiApi as b, SlotTags as c, Target as d, types_d_exports as f, SfxDescriptor as g, PlayDescriptor as h, BuildTools as i, types_d_exports$2 as k, SlotValues as l, HapticDescriptor as m, AnimationDefinition as n, FramesValue as o, ExternalPlayer as p, AnimationSpec as r, MotionKeyframe as s, AnimApi as t, State as u, Config$1 as v, State$2 as w, types_d_exports$1 as x, State$1 as y };
1734
+ export { UiApi as A, spawned as C, wait as D, use as E, TextApi as F, TextStyleInput as I, TextStyles as L, Config$2 as M, Point as N, Config$1 as O, State$2 as P, TextValue as R, spawn as S, tween as T, parallel as _, State as a, set as b, HapticKind as c, HAPTIC_KINDS as d, defineAnimation as f, mark as g, haptic as h, MotionKeyframe as i, types_d_exports$1 as j, State$1 as k, SfxDescriptor as l, frames as m, Config as n, Target as o, external as p, FramesValue as r, types_d_exports as s, AnimApi as t, Step as u, play as v, stagger as w, sfx as x, sequence as y, types_d_exports$2 as z };
@@ -1,13 +1,14 @@
1
- import { At as Json, C as LayerSpec, Dt as Api$4, F as ComponentHandle, Gt as Events$2, H as Owner, I as ComponentType, R as Entity, S as LayerSort, St as Api$3, a as PixiSprite, d as FilterSlot, h as Api$1, i as PixiModule, kt as Events$1, nn as Require, o as PixiTexture, p as Point, q as Api, r as PixiFilter, t as Api$2, vt as Descriptor } from "./types-Cjf3ywai.mjs";
2
- import { o as Events$3, t as Api$5 } from "./types-DgwbzDLP.mjs";
3
- import { t as AnimApi } from "./types-KlE_GL1z.mjs";
1
+ import { At as Json, C as LayerSpec, Dt as Api$4, F as ComponentHandle, Gt as Events$2, H as Owner, I as ComponentType, R as Entity, S as LayerSort, St as Api$3, a as PixiSprite, d as FilterSlot, h as Api$1, i as PixiModule, kt as Events$1, nn as Require, o as PixiTexture, p as Point, q as Api, r as PixiFilter, t as Api$2, vt as Descriptor } from "./types-BZ1OLf24.mjs";
2
+ import { o as Events$3, t as Api$5 } from "./types-C47fKNcn.mjs";
3
+ import { t as AnimApi } from "./types-CqkrEY06.mjs";
4
4
  import { Log } from "@moku-labs/common/browser";
5
5
  import { PluginCtx } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/effects/filters/types.d.ts
8
8
  /**
9
- * One uniform of a custom filter, as declared: a number is an `f32`, `{ color }` a `0xrrggbb`
10
- * hex sent as a `vec3<f32>`, a tuple of 2 to 4 numbers a `vecN<f32>`.
9
+ * One uniform of a custom filter, as declared: a number is an `f32` (`float` in GLSL), `{ color }`
10
+ * a `0xrrggbb` hex sent as a `vec3<f32>` (`vec3`), a tuple of 2 to 4 numbers a `vecN<f32>`
11
+ * (`vecN`).
11
12
  *
12
13
  * @example
13
14
  * ```ts
@@ -44,19 +45,28 @@ type FilterValueOf<Uniforms extends Record<string, UniformDeclaration>> = { -rea
44
45
  order: number;
45
46
  };
46
47
  /**
47
- * What `defineFilter` takes besides the id. `wgsl` is the fragment body only; the engine
48
- * prepends the vertex stage, the input bindings and the `FilterUniforms` struct.
48
+ * What `defineFilter` takes besides the id. Both bodies are required, so the filter draws on
49
+ * WebGPU and on the WebGL fallback: `wgsl` is the WGSL fragment body only, the engine prepends the
50
+ * vertex stage, the input bindings and the `FilterUniforms` struct; `glsl` is its GLSL ES 3.0 twin
51
+ * over the same uniform names, the engine prepends the version, the inputs, `finalColor` and one
52
+ * `uniform` per declared uniform.
49
53
  *
50
54
  * @example
51
55
  * ```ts
52
56
  * const spec: FilterSpec<{ amount: number }> = {
53
57
  * wgsl: "@fragment fn mainFragment(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { return textureSample(uTexture, uSampler, uv) * fu.amount; }",
58
+ * glsl: "void main() { finalColor = texture(uTexture, vTextureCoord) * amount; }",
54
59
  * uniforms: { amount: 1 }
55
60
  * };
56
61
  * ```
57
62
  */
58
63
  type FilterSpec<Uniforms extends Record<string, UniformDeclaration>> = {
59
- /** The fragment body: `fn mainFragment` and its helpers, without the engine's header. */readonly wgsl: string; /** The uniforms in struct order. Default `{}`. */
64
+ /** The WGSL fragment body: `fn mainFragment` and its helpers, without the engine's header. */readonly wgsl: string;
65
+ /**
66
+ * The GLSL ES 3.0 fragment body: `void main()`, which sets `finalColor`, and its helpers, without
67
+ * the engine's header. It reads each uniform under its bare name: `amount`, not `fu.amount`.
68
+ */
69
+ readonly glsl: string; /** The uniforms in struct order. Default `{}`. */
60
70
  readonly uniforms?: Uniforms; /** Render passes one apply of the filter costs, an integer of at least 1. Default `1`. */
61
71
  readonly passes?: number; /** Pixels around the view's bounds, or the name of a number uniform whose live value they are. Default `0`. */
62
72
  readonly padding?: number | string;
@@ -76,18 +86,21 @@ type UniformSpec = {
76
86
  readonly size: number;
77
87
  };
78
88
  /**
79
- * The filter a component made by `defineFilter` carries: the assembled WGSL, the uniforms in
80
- * struct order, the passes one apply costs and the padding.
89
+ * The filter a component made by `defineFilter` carries: the assembled WGSL in `source`, the
90
+ * assembled GLSL in `glsl`, the uniforms in struct order, the passes one apply costs and the
91
+ * padding.
81
92
  *
82
93
  * @example
83
94
  * ```ts
84
- * Tint.filter.passes; // 1
95
+ * Tint.filter.source.includes("fn mainFragment"); // true: the WGSL, drawn on WebGPU
96
+ * Tint.filter.glsl.startsWith("#version 300 es"); // true: the GLSL, drawn on WebGL
85
97
  * Tint.filter.uniforms.map(uniform => uniform.name); // ["amount", "color"]
86
98
  * ```
87
99
  */
88
100
  type FilterDefinition = {
89
- readonly id: string;
90
- readonly source: string;
101
+ readonly id: string; /** The assembled WGSL: the engine's header, the uniform struct, the body. */
102
+ readonly source: string; /** The assembled GLSL ES 3.0: the engine's header, one `uniform` per uniform, the body. */
103
+ readonly glsl: string;
91
104
  readonly uniforms: readonly UniformSpec[];
92
105
  readonly passes: number;
93
106
  readonly padding: number | string;
@@ -99,7 +112,7 @@ type FilterDefinition = {
99
112
  * @example
100
113
  * ```ts
101
114
  * const Tint: FilterComponent<{ amount: number; enabled: boolean; order: number }> =
102
- * defineFilter("fx.tint", { wgsl: tintBody, uniforms: { amount: 0 } });
115
+ * defineFilter("fx.tint", { wgsl: tintWgsl, glsl: tintGlsl, uniforms: { amount: 0 } });
103
116
  * Tint.componentName; // "fx.tint"
104
117
  * ```
105
118
  */
@@ -242,7 +255,8 @@ type AlphaValue = {
242
255
  */
243
256
  type CoreKind = "blur" | "colorMatrix" | "noise" | "displacement" | "alpha";
244
257
  /**
245
- * Where a filter kind comes from: our or a game's WGSL, or a Pixi core filter.
258
+ * Where a filter kind comes from: our or a game's shaders (`"wgsl"`, with the GLSL twin beside
259
+ * it), or a Pixi core filter.
246
260
  */
247
261
  type KindSource = {
248
262
  readonly source: "wgsl";
@@ -547,9 +561,9 @@ type State$2 = {
547
561
  instances: Map<Entity, EmitterInstance>; /** World-space instances whose host left, stepped until empty. */
548
562
  orphans: Set<EmitterInstance>; /** Ordinal of the next instance: the cosmetic seed. */
549
563
  seedCounter: number; /** Live particles after the last step. */
550
- particles: number; /** Filter kinds whose WGSL failed the dev check. */
564
+ particles: number; /** Filter kinds whose shader failed the dev check on the running backend. */
551
565
  broken: Set<string>; /** The filter kinds, built-ins first, then the filters of every feature. */
552
- kinds: Map<string, FilterKind>; /** The dev WGSL check per kind; `broken` holds the failed ones. */
566
+ kinds: Map<string, FilterKind>; /** The dev shader check per kind; `broken` holds the failed ones. */
553
567
  checks: Map<string, "pending" | "ok">; /** Entity to the filters the sync keeps for it. */
554
568
  views: Map<Entity, FilteredView>; /** Keys of the one-shot warnings: `"emitter:fx.x"`, `"texture:board.cell"`, `"atlas:fx.x"`. */
555
569
  warned: Set<string>; /** Whether each budget warning is in force, so a crossing warns once. */
@@ -1,4 +1,4 @@
1
- import { At as Json, Ht as RngState, St as Api, ft as FlowState, ht as RouteStep, pt as JournalEntry, q as Api$1, xt as Answer, zt as Snapshot } from "./types-Cjf3ywai.mjs";
1
+ import { At as Json, Ht as RngState, St as Api, ft as FlowState, ht as RouteStep, pt as JournalEntry, q as Api$1, xt as Answer, zt as Snapshot } from "./types-BZ1OLf24.mjs";
2
2
  import { Log } from "@moku-labs/common/browser";
3
3
 
4
4
  //#region src/plugins/flow/headless.d.ts
@@ -1,4 +1,4 @@
1
- import { At as Json, D as ProjectionMotion, I as ComponentType, L as ComponentValue, N as AnyComponentType, P as AnyComponentValue, R as Entity, St as Api, T as MotionHandle, bt as Hint, h as Api$2, j as ViewHandle, m as ViewportSize, nn as Require, p as Point$1, q as Api$1, t as Api$3, vt as Descriptor, w as Motion, y as ChangeHook } from "./types-Cjf3ywai.mjs";
1
+ import { At as Json, D as ProjectionMotion, I as ComponentType, L as ComponentValue, N as AnyComponentType, P as AnyComponentValue, R as Entity, St as Api, T as MotionHandle, bt as Hint, h as Api$2, j as ViewHandle, m as ViewportSize, nn as Require, p as Point$1, q as Api$1, t as Api$3, vt as Descriptor, w as Motion, y as ChangeHook } from "./types-BZ1OLf24.mjs";
2
2
  import { Log } from "@moku-labs/common/browser";
3
3
  import { PluginCtx } from "@moku-labs/core";
4
4
 
@@ -0,0 +1,105 @@
1
+ The MSDF body font of this folder is built from a Google Font released under the SIL Open Font
2
+ License 1.1. The licence text follows.
3
+
4
+ - font-body.fnt, font-body.png: Pangolin Regular (Pangolin-Regular.ttf).
5
+
6
+ ================================================================================
7
+
8
+ Pangolin
9
+
10
+ ================================================================================
11
+
12
+
13
+ Copyright 2016 The Pangolin Project Authors (https://github.com/googlefonts/pangolin)
14
+
15
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
16
+ This license is copied below, and is also available with a FAQ at:
17
+ http://scripts.sil.org/OFL
18
+
19
+
20
+ -----------------------------------------------------------
21
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
22
+ -----------------------------------------------------------
23
+
24
+ PREAMBLE
25
+ The goals of the Open Font License (OFL) are to stimulate worldwide
26
+ development of collaborative font projects, to support the font creation
27
+ efforts of academic and linguistic communities, and to provide a free and
28
+ open framework in which fonts may be shared and improved in partnership
29
+ with others.
30
+
31
+ The OFL allows the licensed fonts to be used, studied, modified and
32
+ redistributed freely as long as they are not sold by themselves. The
33
+ fonts, including any derivative works, can be bundled, embedded,
34
+ redistributed and/or sold with any software provided that any reserved
35
+ names are not used by derivative works. The fonts and derivatives,
36
+ however, cannot be released under any other type of license. The
37
+ requirement for fonts to remain under this license does not apply
38
+ to any document created using the fonts or their derivatives.
39
+
40
+ DEFINITIONS
41
+ "Font Software" refers to the set of files released by the Copyright
42
+ Holder(s) under this license and clearly marked as such. This may
43
+ include source files, build scripts and documentation.
44
+
45
+ "Reserved Font Name" refers to any names specified as such after the
46
+ copyright statement(s).
47
+
48
+ "Original Version" refers to the collection of Font Software components as
49
+ distributed by the Copyright Holder(s).
50
+
51
+ "Modified Version" refers to any derivative made by adding to, deleting,
52
+ or substituting -- in part or in whole -- any of the components of the
53
+ Original Version, by changing formats or by porting the Font Software to a
54
+ new environment.
55
+
56
+ "Author" refers to any designer, engineer, programmer, technical
57
+ writer or other person who contributed to the Font Software.
58
+
59
+ PERMISSION & CONDITIONS
60
+ Permission is hereby granted, free of charge, to any person obtaining
61
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
62
+ redistribute, and sell modified and unmodified copies of the Font
63
+ Software, subject to the following conditions:
64
+
65
+ 1) Neither the Font Software nor any of its individual components,
66
+ in Original or Modified Versions, may be sold by itself.
67
+
68
+ 2) Original or Modified Versions of the Font Software may be bundled,
69
+ redistributed and/or sold with any software, provided that each copy
70
+ contains the above copyright notice and this license. These can be
71
+ included either as stand-alone text files, human-readable headers or
72
+ in the appropriate machine-readable metadata fields within text or
73
+ binary files as long as those fields can be easily viewed by the user.
74
+
75
+ 3) No Modified Version of the Font Software may use the Reserved Font
76
+ Name(s) unless explicit written permission is granted by the corresponding
77
+ Copyright Holder. This restriction only applies to the primary font name as
78
+ presented to the users.
79
+
80
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
81
+ Software shall not be used to promote, endorse or advertise any
82
+ Modified Version, except to acknowledge the contribution(s) of the
83
+ Copyright Holder(s) and the Author(s) or with their explicit written
84
+ permission.
85
+
86
+ 5) The Font Software, modified or unmodified, in part or in whole,
87
+ must be distributed entirely under this license, and must not be
88
+ distributed under any other license. The requirement for fonts to
89
+ remain under this license does not apply to any document created
90
+ using the Font Software.
91
+
92
+ TERMINATION
93
+ This license becomes null and void if any of the above conditions are
94
+ not met.
95
+
96
+ DISCLAIMER
97
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
98
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
99
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
100
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
101
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
102
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
103
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
104
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
105
+ OTHER DEALINGS IN THE FONT SOFTWARE.